将花岗岩验证错误作为 JSON 返回



我有一个花岗岩User模型,并进行了一些验证。当有人向users/new发出POST请求时,我想将验证错误(如果有(作为 JSON 返回。目前,我有:

if user.errors.size > 0
halt env, status_code: 500, response: user.errors.to_json
end

但是当我尝试编译时,我得到:

in /usr/local/Cellar/crystal/0.26.1/src/json/to_json.cr:66: no overload 
matches 'Granite::Error#to_json' with type JSON::Builder
Overloads are:
- Object#to_json(io : IO)
- Object#to_json()
each &.to_json(json)
^~~~~~~

所以问题是User#errors是一个Array(Granite::Error),即一个持有Granite::Errors的Array。 不幸的是,看起来Granite::Error并没有实现Array#to_json依赖的to_json(JSON::Builder)方法(即该方法to_json采用类型为JSON::Builder的参数(,您在那里看到的片段来自您可以在 GitHub 上查看的Array#to_json的实现。

我建议使用JSON.build自己构建 JSON。这有一个额外的副作用,即保持你响应的JSON(我想它被某个客户端使用(完全在你的控制之下。如果 Granite 的开发人员要更改他们在 JSON 中编码Granite::Error的方式,并且您使用的是他们的to_json方法,则更改不会在编译时引发任何内容。

作为旁注,我建议不要使用状态代码 500 来表示验证错误,因为这通常是为服务器内部的意外错误保留的。4xx 错误(例如 400 - 错误请求(会更合适。作为第二个旁注,对/users端点进行POST会更 RESTful,而不是/users/new

通过这些更改,结果代码段如下:

if user.errors.size > 0
errors_as_json = JSON.build do |json|
json.array do
user.errors.each do |error|
json.string error.to_s
end
end
end
halt env, status_code: 400, response: errors_as_json
end

相关内容

  • 没有找到相关文章

最新更新