新手问题 Grape 的 JSON 参数验证,以及 nested params 问题

seaify · 2015年08月30日 · 最后由 gwq 回复于 2017年12月28日 · 3219 次阅读

两个问题

  1. grape,看文档并不支持对json parameters, 进行require等操作? 它的require 一个参数后,实际上对应生成的swagger-ui,都是form表单,而且通过postman,也只有以form形式提交的请求才正常
  2. grape, 对于nested params, 似乎一直报错?
params do
  requires :id, type: Integer, desc: "播放器id"
  requires :name, type: Hash do
    requires :first_name
    requires :last_name
  end
end

而另一种写法

params do
       requires :id, type: Integer, desc: "播放器id"
       requires "name[first]", type: Integer, desc: "空闲内存"
       requires "name[last]", type: Integer, desc: "空闲内存"
     end

共收到 23 条回复

grape 使用好像没有发现类似的问题。你先在log 中,看看 post 后,grape 解析后的参数。

http request header中设置content-type 为application/json,传json参数是没有问题的

#2楼 @alucardpj

传递json参数确实没问题,我说的问题是,比如这个json {"name": "chuck"},我需要确认json中这个name字段要有,如果使用requires :name, 没有作用,

传json参数要设置Content-Type header为application/json, grape会调用自带的Grape::Parser::Json去解析。

可参考API Data Formats文档: https://github.com/ruby-grape/grape#api-data-formats

我比较奇怪

requires :name, type: Hash do
  requires :first_name
  requires :last_name
end

为什么还会出现 name filed,按道理应该只会出现name[first_name], name[last_name]?

#5楼 @justin

这个我也奇怪,因为name出现,根本就不是我想要的,peatio的api文档也是这样的,https://yunbi.com/documents/api_v2#!/orders/POST_version_orders_multi_format

正是因为这个奇怪的问题,我才改成下面那样去绕

requires "name[first]", type: Integer, desc: "空闲内存"
requires "name[last]", type: Integer, desc: "空闲内存"

#4楼 @jan

感谢你的回复,明白了该怎么去自定义数据format。

我更关心的是json的这种数据格式,能否通过params, requires, desc这些关键字来对参数验证,以及swagger-ui能否合理的根据这些api信息合理的生成相应的页面,用来方便的模拟请求。

#6楼 @seaify

grape (0.11.0)
grape-swagger (0.10.1)
grape-swagger-rails (0.1.0)

我这边这个版本是不会有问题的 而且我看到peatio的api里面orders的Data Type是Array

不知道 grape swagger rails 有没有暴露出定义的选项,swagger ui 是支持 body 参数使用 JSON 的,但是发的时候需要自己把整个 JSON 复制进去 (有 JSON scehma 验证,也可以一键填充默认的 JSON) 没有表单的提交方式,长得像这样

#10楼 @doitian

非常感谢,这正是我想要看的。grape-swagger的文档里看到有这个,param_type: 'body',还没试。

你的这个效果图,是swagger-ui结合什么弄出来的?

另外看这个图,grape应该是没有办法支持指定body这个json里,必须包含name字段,这种限制条件吧?

#9楼 @hammer

感谢回复。

我也有用了ActionController::Parameters,只是你的这段代码,看样子,是处理form表单,且字段名是project[xxx],可我想要的是json。

#8楼 @justin

嗯。版本问题,我这边版本低了,和peatio一样。不过Data Type是Array,即便是array, 我的理解里,也不应该有name这个字段。

#8楼 @justin

囧。升级后,直接不可用了。

ActionController::RoutingError (No route matches [GET] "/api/v1/swagger_doc/screens.json"):

路由找不到了。估计add_swagger_documentation,生成的那个url,其包含的json信息不对了。

mount API => '/'
mount GrapeSwaggerRails::Engine => '/api/docs'

这是我router的配置

#15楼 @justin

我没有用grape-swagger-rails,是直接把swagger-ui的那些js, css文件拷贝到asset, 而那些路由是ruby-china,和peatio两边都参考了下。

我也试下grape-swagger-rails

请问你的问题解决了没有?我也遇到同样问题。

#17楼 @lelewan

我不知道你说的是什么问题。

我现在没有使用param requires这些,使用的gem的版本

gem 'grape', '~> 0.7.0'
gem 'grape-entity', '~> 0.4.2'
gem 'grape-swagger', '~> 0.7.2'

gem升级后的问题没有解决, 还没有尝试grape-swagger-rails,直接在做另一个项目了。

@seaify 我用curl请求hash格式通不过requires校验,后来改用rest_client就可以了,应该是我curl格式搞错了,谢谢回复。

#19楼 @lelewan

能不能贴上你的grape函数,只需要包含require部分,以及你使用的rest_client post过来的时候content-type是json吗?

@seaify

desc "增加资源"
params do
  requires :field, type: Hash, allow_blank: false do
    requires : field1, type: String, allow_blank: false
    requires : field2, type: String, allow_blank: false
  end
end
post do
  result = REDIS.hgetall:"#{params[:field][:field1]}"
  if result.blank? 
      REDIS.hset:"#{params[:field][:field1]}",FIELD2,"#{params[:field][:field2]}"  
  else
    {:error => "#{params[:field][:field1]}已经存在" }
  end
end

rest-client安装后执行restclient。终端请求格式:

RestClient.post "http://localhost:9000/api/v1/demo", { 'field' => {'field1' => 'X12345','field2' => 'iii'} }.to_json, :content_type => :json, :accept => :json

#10楼 @doitian 请教一下这个图grape是怎么写的?

params do
  requires :body
end

这样的json会多出来一层。

seaify 回复

我也遇到这种问题了,请问该怎么解决

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册