Servant QueryParams 解析错误
Servant QueryParams parse error
给定以下代码:
newtype HelloMessage = HelloMessage { msg :: String }
deriving (Generic)
instance ToJSON HelloMessage
type API2 = "hello"
:> QueryParam "age" Int
:> Get '[JSON] HelloMessage
appAPI2 :: Proxy API2
appAPI2 = Proxy
myHandler :: Server API2
myHandler = helloHandler
where
helloHandler :: Maybe Int -> Handler HelloMessage
helloHandler mAge =
let
sAge = case mAge of
Nothing -> "0"
Just ag -> show ag
in
return . HelloMessage $ sAge
app2 :: Application
app2 = serve appAPI2 myHandler
main :: IO ()
main = run 8080 app2
我可以访问 /hello
,其中 return 是 { "msg" : 0}
或 /hello?age=20
,其中 return 是 { "msg" : 20}
。但是,如果我将年龄设置为可解析的非整数,例如"foobar"
这使得 url 成为 /hello?age=foobar
并访问它,它 return 是关于 "foobar"
.
上的解析错误的错误消息
这与 Capture
的行为不同,如果我给予相同的处理,它只会 return 一个 http 400。
我的代码有什么问题?
编辑:经过进一步探索,它确实 return http 400 解析错误。现在我正在改变问题。如何 return 自定义错误信息 if
那会发生吗?
QueryParam
的默认行为是这样的:如果无法解码则出错,但 return 未指定时无任何内容。
从 servant 0.13 开始,您可以覆盖它。
如果你查看 the definition of QueryParam
,你会发现它实际上只是更一般的 QueryParam'
类型的特例:
type QueryParam = QueryParam' '[Optional, Strict]
QueryParam'
采用我们所说的 "modifiers",这会影响两件事:
- 是否可以在没有此参数值的情况下生存:如果可以,您的处理程序将获得一个
Maybe a
,否则您将直接获得一个 a
,但是当没有给出值时它会出错.这是 Required
对比 Optional
.
- 你是否希望解码失败是致命的:如果你这样做,那么当解码失败时,你的仆人会出错,否则你的处理程序会得到一个
a
。如果你不这样做,那么你的处理程序会得到一个 Either Text a
然后你可以在解码错误的情况下自由地做任何你想做的事情(这是 Either
的 Left
情况,带有文本错误消息)。这是 Strict
对比 Lenient
.
所以你可能想定义类似 type MyQueryParam name a = QueryParam' '[Optional, Lenient]
的东西,并在适当的时候使用它。
这是否解决了您的问题?
给定以下代码:
newtype HelloMessage = HelloMessage { msg :: String }
deriving (Generic)
instance ToJSON HelloMessage
type API2 = "hello"
:> QueryParam "age" Int
:> Get '[JSON] HelloMessage
appAPI2 :: Proxy API2
appAPI2 = Proxy
myHandler :: Server API2
myHandler = helloHandler
where
helloHandler :: Maybe Int -> Handler HelloMessage
helloHandler mAge =
let
sAge = case mAge of
Nothing -> "0"
Just ag -> show ag
in
return . HelloMessage $ sAge
app2 :: Application
app2 = serve appAPI2 myHandler
main :: IO ()
main = run 8080 app2
我可以访问 /hello
,其中 return 是 { "msg" : 0}
或 /hello?age=20
,其中 return 是 { "msg" : 20}
。但是,如果我将年龄设置为可解析的非整数,例如"foobar"
这使得 url 成为 /hello?age=foobar
并访问它,它 return 是关于 "foobar"
.
这与 Capture
的行为不同,如果我给予相同的处理,它只会 return 一个 http 400。
我的代码有什么问题?
编辑:经过进一步探索,它确实 return http 400 解析错误。现在我正在改变问题。如何 return 自定义错误信息 if 那会发生吗?
QueryParam
的默认行为是这样的:如果无法解码则出错,但 return 未指定时无任何内容。
从 servant 0.13 开始,您可以覆盖它。
如果你查看 the definition of QueryParam
,你会发现它实际上只是更一般的 QueryParam'
类型的特例:
type QueryParam = QueryParam' '[Optional, Strict]
QueryParam'
采用我们所说的 "modifiers",这会影响两件事:
- 是否可以在没有此参数值的情况下生存:如果可以,您的处理程序将获得一个
Maybe a
,否则您将直接获得一个a
,但是当没有给出值时它会出错.这是Required
对比Optional
. - 你是否希望解码失败是致命的:如果你这样做,那么当解码失败时,你的仆人会出错,否则你的处理程序会得到一个
a
。如果你不这样做,那么你的处理程序会得到一个Either Text a
然后你可以在解码错误的情况下自由地做任何你想做的事情(这是Either
的Left
情况,带有文本错误消息)。这是Strict
对比Lenient
.
所以你可能想定义类似 type MyQueryParam name a = QueryParam' '[Optional, Lenient]
的东西,并在适当的时候使用它。
这是否解决了您的问题?