Tôi là người mới bắt đầu sử dụng Haskell và hiện đang sử dụng wreq để tạo một trình bao bọc đơn giản xung quanh một api. Tôi muốn gửi tiêu đề if-modified-since
nếu được cung cấp cùng một lúc. Tôi đang làm như vậy theo cách sau.Haskell/Wreq - Lời khuyên về chữ ký phức tạp cho các yêu cầu http
getResponse :: (FormatTime t, Exception e) => File -> Maybe t -> IO (Either e (Response L.ByteString))
getResponse file (Just t) =
let formattedTime = (B.pack . formatTime defaultTimeLocale rfc822DateFormat) t
opts = defaults & header "if-modified-since" .~ [formattedTime]
in try $ getWith opts $ buildUrl file
getResponse file Nothing = try $ (get $ buildUrl file)
tôi nhận thấy rằng 304 (not modified)
phản ứng đang trở lại như trường hợp ngoại lệ như vậy đó là biện minh của tôi cho việc sử dụng các loại Either
. Tôi muốn cung cấp khả năng hiển thị lỗi cho những người có thể sử dụng trình bao bọc api này.
Giả sử yêu cầu thành công, tôi muốn phân tích cú pháp nội dung phản hồi thành một loại tương ứng được xác định trong thư viện của tôi. Có một cơ hội deserialization có thể không hoạt động chính xác nếu một cái gì đó thay đổi trên máy chủ tôi đang yêu cầu để vì vậy tôi đã chọn để sử dụng loại Maybe
để giải thích cho việc này.
getPayload :: FromJSON b => (Either e (Response L.ByteString)) -> Either e (Maybe b)
getPayload (Left _) = return Nothing
getPayload (Right a) = return $ fmap Just (^. responseBody) =<< asJSON a
Chữ ký của các chức năng này bắt đầu có vẻ giống như tôi, điều gì đó trong ruột cho tôi biết có cách tốt hơn nhưng tôi không chắc chắn. Một điều tôi đã làm là tạo ra một chức năng khác để đặt chúng cùng với hy vọng nó sẽ dễ sử dụng hơn. Đây là hàm tôi định sử dụng để tạo các hàm khác để thực hiện các yêu cầu cụ thể hơn đối với tài nguyên cá nhân.
getResource :: (Exception e, FormatTime t, FromJSON b) => File -> Maybe t -> IO (Either e (Maybe b))
getResource f t = getPayload <$> (getResponse f t)
Bây giờ tôi phải xử lý 3 lớp cấu trúc khi xử lý yêu cầu http. IO
, Either
và Maybe
. Tôi có làm quá phức tạp không? Tôi có thể làm gì để giảm bớt nỗi đau khi làm việc với quan điểm sử dụng và bảo trì? Làm thế nào tôi có thể cải thiện điều này?
Bạn không thể làm phẳng 'Hoặc e (Có thể b) 'thành' Hoặc e b', trong đó 'e' cũng có thể mang thông tin về lỗi thất bại? 'Có thể b' là đẳng cấu cho' Hoặc() b'. –
Tôi muốn xem xét sử dụng kiểu dữ liệu tùy chỉnh 'data ResourceResult b = Error e | NotModified | Kết quả b'. Tổng thư viện và các loại sản phẩm là tốt, nhưng không hương vị: chúng rất chung chung đến mức chúng không truyền đạt ý nghĩa. Tốt hơn là nên sử dụng loại tùy chỉnh có tên phù hợp, gợi nhiều gợi ý. – chi
Cảm ơn bạn đã giới thiệu @chi này. Tôi sẽ ghi nhớ điều này. –