我正在使用 Htmx 将表单发布到 Haskell Servant 端点。端点有一个带有
FromForm
实例的模型。表单中有一个可选字段。如果 POST 中排除了该字段,客户端将收到 400 响应“Unexpected end-of-input, waiting -, +, or a digital”,表示解析失败。
-- | Reading model.
data Reading = Reading
{ title :: String
, authors :: Vector String
, startDate :: Day
, endDate :: Maybe Day
}
deriving (Eq, Show, Generic, ToJSON, FromJSON, FromRow)
-- | Allow form construction of a `Reading` instance.
instance FromForm Reading where
fromForm :: Form -> Either Text Reading
fromForm f =
Reading
<$> parseUnique "title" f
<*> (fromList <$> parseAll "authors" f)
<*> parseUnique "startDate" f
<*> parseMaybe "endDate" f
实际发布的 FormUrlEncoded 字节字符串是
title=asdf&authors=asdf&startDate=2024-03-01&endDate=
。我该如何解决这个问题?我怀疑有一种方法可以让servant优雅地处理这个问题,但我也在考虑客户端的改变(尽管这似乎不太理想)。
我看过这篇文章,但觉得必须有一种替代方法来包装
Maybe
。另外,也许我可以通过 Htmx 针对我的特定用例做一些事情。
我找到了一个通用解析器函数,其签名由@Ismor建议。
它按预期工作,我想在处理传入的表单数据时我将始终使用它来代替
parseMaybe
。
parseOptionalMaybe :: FromHttpApiData v => Text -> Form -> Either Text (Maybe v)
parseOptionalMaybe fieldName form = do
maybeField <- lookupMaybe fieldName form
case maybeField of
Just "" -> return Nothing
Just _ -> parseMaybe fieldName form
Nothing -> return Nothing