将Granite验证错误作为JSON返回

问题描述 投票:0回答:1

我有一个花岗岩User模型与一些验证。当有人向POST发出users/new请求时,我想将验证错误(如果有的话)作为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)
         ^~~~~~~
crystal-lang kemal
1个回答
1
投票

所以问题是User#errors是一个Array(Granite::Error),即持有Arrays的Granite::Error。不幸的是,它看起来不像Granite::Error实现to_json(JSON::Builder)方法(即to_json类型为JSON::Builder的方法Array#to_json),Array#to_json依赖于(你看到的那个片段来自view on GitHub的实现,你可以JSON.build。)。

我建议你自己使用Granite::Error构建JSON。这有另外的副作用,即保持您响应的JSON(我想象的是由某个客户端使用)完全由您控制。如果Granite的开发人员要改变他们在JSON中编码to_jsons的方式并且你使用他们的POST方法,那么更改不会在编译时引发任何事情。

作为旁注,我建议不要使用状态代码500来表示验证错误,因为这通常是为服务器内部的意外错误保留的。 4xx错误(例如400 - 错误请求)会更合适。作为第二个侧面说明,与/users相反,将/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 端点会更加RESTful。

通过这些更改,以下是生成的代码段:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.