使用Yesod验证JSON请求的最佳实践

使用Yesod验证JSON请求的最佳实践,json,rest,haskell,yesod,Json,Rest,Haskell,Yesod,我正在用Yesod编写JSON RESTFul服务,需要实现请求验证。 因为服务接受JSON,所以我不能使用Yesod.Form。我喜欢使用的方式,但我在Haskell中没有找到类似的方法 是否有实施验证的最佳实践,允许回答结构化错误消息,如: 要求 回应 我建议使用aeson的本机解析功能,它将同时解析传入的JSON并将其转换为Haskell数据结构。有一个库,它利用Text.desculse.Form,并允许编写表达性验证规则。以下是its的要点: pokeForm::Monad m=>Fo

我正在用Yesod编写JSON RESTFul服务,需要实现请求验证。 因为服务接受JSON,所以我不能使用Yesod.Form。我喜欢使用的方式,但我在Haskell中没有找到类似的方法

是否有实施验证的最佳实践,允许回答结构化错误消息,如:

要求 回应
我建议使用aeson的本机解析功能,它将同时解析传入的JSON并将其转换为Haskell数据结构。

有一个库,它利用
Text.desculse.Form
,并允许编写表达性验证规则。以下是its的要点:

pokeForm::Monad m=>Form Text m Pokemon
pokeForm=Pokemon“name”。:nonEmptyText
“数字”。:解析整数
哪里
nonEmptyText=检查“名称不能为空”(not.T.null)$
不发短信
testPokedexFailHead=
let(v,r)=runIdentity$digestJSON pokedexForm json
在测试组中“使用单个无效项提交pokedex”
[testCase“验证失败”$r@?=无
,testCase“jsonErrors显示正确的错误”$jsonErrors v@?=错误
]
哪里
(仅json)=解码“{\'pokemon\\”:[{\'name\':\'}]}”
(仅错误)=解码“{\'pokemon\”:[{\'name\':\'name不能为空\'}]}”

正如您所看到的,该库可能会产生相当详细的错误,这些错误标有未通过验证的字段名。

不幸的是,Aeson无法生成详细的错误,其中包含未通过验证的字段及其原因。但我明白你的意思:YesSOD中没有验证JSON的最佳实践,请随意使用外部解决方案。值得一提的是:
消化函数aeson
仍在维护中,但不再处于开发阶段。此外,IMHO
消化函子
在一开始就不适合验证JSON。目前正在寻找另一个解决方案<代码>格式看起来很有趣。
{
    "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"
        }
    }
}
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\"}]}"