我正在使用Yesod编写JSON RESTFul服务,需要实现请求验证。 因为服务接受JSON,我不能使用Yesod.Form。我喜欢scalaz validation使用的方式,但我在Haskell中找不到这样的方法。
是否有最佳实践可以实现验证,以便回答结构化错误消息,如下所示:
{
"birthDate": "2017.07.14",
"count": "three",
"kind": "baz",
"entity": {
"id": -1
}
}
{
"errors": {
"birthDate": "Date should be less than 2014.05.25", // current date
"count": "should be a number",
"kind": "must be one of [foo, bar]",
"entity": {
"id": "Entity with id -1 not found"
}
}
}
答案 0 :(得分:7)
我建议使用aeson的本机解析功能,这将同时解析传入的JSON并将其转换为Haskell数据结构。
答案 1 :(得分:5)
有一个digestive-functors-aeson库利用Text.Digestive.Form
并允许编写表达式验证规则。以下是tests:
pokeForm :: Monad m => Form Text m Pokemon
pokeForm = Pokemon <$> "name" .: nonEmptyText
<*> "number" .: parseInteger
where
nonEmptyText = check "Name cannot be empty" (not . T.null) $
text Nothing
testPokedexFailHead =
let (v, r) = runIdentity $ digestJSON pokedexForm json
in testGroup "Submit pokedex with a single invalid item"
[ testCase "Failed validation" $ r @?= Nothing
, testCase "jsonErrors shows correct errors" $ jsonErrors v @?= errors
]
where
(Just json) = decode "{\"pokemon\":[{\"name\":\"\"}]}"
(Just errors) = decode "{\"pokemon\":[{\"name\":\"Name cannot be empty\"}]}"
正如您所看到的,该库可以生成非常详细的错误,这些错误标记为验证失败的字段名称。