如何将我的API限制为只接受和响应Rails和葡萄上的json格式,我已经在我的葡萄控制器上尝试了format :json
,并且(例如)我可以在example.com/api/v1/ping.json上访问它,但是我也可以通过example.com/api/v1/ping.xml、example.com/api/v1/ping.foobar访问它,并且扩展列表继续进行。
我想要做的事情是,在example.com/api/v1/ping.not_json_扩展名上抛出错误
我正在使用:
/config/routes.rb
mount API::Base => '/api'
/controllers/api/base.rb
module API
class Base < Grape::API
mount API::V1::Base
end
end
/controllers/api/v1/base.rb
module API
module V1
class Base < Grape::API
format :json
mount API::V1::Ping
end
end
结束
/controllers/api/v1/ping.rb
module API
module V1
class Ping < Grape::API
include API::V1::Defaults
desc 'Returns pong.'
get :ping do
{ ping: params[:pong] || 'pong' }
end
end
end
结束
发布于 2014-06-21 16:18:11
从葡萄源代码的角度来看,这似乎是计划中的行为,但为了防止内存泄漏而进行的更改实际上破坏了它。
您可以“手动”实现正确的行为,方法是向API类添加一个显式检查(in /controllers/api/base.rb):
before do
# Make sure the format specified by the request extension is one
# we support
parts = request.path.split('.')
if parts.size > 1
extension = parts.last
if !extension.eql? 'json'
throw :error, {
status: 406,
message: "The requested format '#{extension}' is not supported."
}
end
end
end
这段代码几乎是逐字从Grape的源代码(在lib/葡萄/中间件/formatter.rb中)复制的,也是Grape本身检查请求中使用的扩展的方式。
在该文件中,negotiate_content_type
负责检查所请求的格式是否是API支持的格式,并明确赋予请求扩展的优先级。但是,解析URI format_from_extension
扩展的方法也会检查格式是否受支持,如果不支持则返回nil
,就好像根本没有扩展一样。因此,如果请求的扩展指定了不受支持的格式,那么negotiate_content_type
永远不会触发错误,尽管它显然是要这样做的。
您可以通过将formatter.rb:109上的代码更改为
# avoid symbol memory leak on an unknown format
return extension.to_sym if content_type_for(extension)
简单地
return extension.to_sym
但是,注释表明代码是这样写的,所以要谨慎行事。
https://stackoverflow.com/questions/24341786
复制相似问题