Nei*_*ter 10 ruby ruby-grape jsend
我有一个小型的原型子类Grape::API作为机架服务,并Grape::Entity用于呈现我的应用程序的内部对象.
我喜欢Grape::EntityDSL,但我很难找到我应该超越默认的JSON表示,这对我们来说太轻了.我被要求以"jsend或类似"格式生成输出:http://labs.omniti.com/labs/jsend
我完全不确定改变的性质与Grape框架最相符(我想在这里采用最小阻力路径).我应该创建一个自定义的Grape格式化程序(我不知道如何做到这一点),新的机架中间件(我这样做是为了通过SysLog记录API输入/输出 - 但格式化似乎很糟糕,因为我需要解析正文从JSON返回以添加容器级别),或者更改Grape::Entity为例如RABL?
示例代码("app.rb")
require "grape"
require "grape-entity"
class Thing
def initialize llama_name
@llama_name = llama_name
end
attr_reader :llama_name
end
class ThingPresenter < Grape::Entity
expose :llama_name
end
class MainService < Grape::API
prefix 'api'
version 'v2'
format :json
rescue_from :all
resource :thing do
get do
thing = Thing.new 'Henry'
present thing, :with => ThingPresenter
end
end
end
Run Code Online (Sandbox Code Playgroud)
Rackup文件("config.ru")
require File.join(File.dirname(__FILE__), "app")
run MainService
Run Code Online (Sandbox Code Playgroud)
我启动它:
rackup -p 8090
Run Code Online (Sandbox Code Playgroud)
并称之为:
curl http://127.0.0.1:8090/api/v2/thing
{"llama_name":"Henry"}
Run Code Online (Sandbox Code Playgroud)
我想看到的:
curl http://127.0.0.1:8090/api/v2/thing
{"status":"success","data":{"llama_name":"Henry"}}
Run Code Online (Sandbox Code Playgroud)
显然我可以做类似的事情
resource :thing do
get do
thing = Thing.new 'Henry'
{ :status => "success", :data => present( thing, :with => ThingPresenter ) }
end
end
Run Code Online (Sandbox Code Playgroud)
在每条路线 - 但这似乎不是很干.我正在寻找更清洁的东西,并且当这个API变得更大并且由整个团队维护时,更不容易削减和粘贴错误
奇怪的是,当我尝试{ :status => "success", :data => present( thing, :with => ThingPresenter ) }使用时grape 0.3.2,我无法让它工作.API返回的值只是present- 这里的内容比我最初想的要多.
Nei*_*ter 15
这是我最终得到的,通过阅读Grape文档,谷歌搜索和阅读github上的一些拉取请求的组合.基本上,在声明:json格式之后(为了得到它带来的所有其他默认好东西),我将输出格式化程序覆盖了添加jsend的包装层的新格式化程序.这比编写Grape的#present帮助程序(不能很好地覆盖错误)或机架中间件解决方案(需要反序列化和重新序列化JSON,以及需要大量额外代码来覆盖错误)更清晰..
require "grape"
require "grape-entity"
require "json"
module JSendSuccessFormatter
def self.call object, env
{ :status => 'success', :data => object }.to_json
end
end
module JSendErrorFormatter
def self.call message, backtrace, options, env
# This uses convention that a error! with a Hash param is a jsend "fail", otherwise we present an "error"
if message.is_a?(Hash)
{ :status => 'fail', :data => message }.to_json
else
{ :status => 'error', :message => message }.to_json
end
end
end
class Thing
def initialize llama_name
@llama_name = llama_name
end
attr_reader :llama_name
end
class ThingPresenter < Grape::Entity
expose :llama_name
end
class MainService < Grape::API
prefix 'api'
version 'v2'
format :json
rescue_from :all
formatter :json, JSendSuccessFormatter
error_formatter :json, JSendErrorFormatter
resource :thing do
get do
thing = Thing.new 'Henry'
present thing, :with => ThingPresenter
end
end
resource :borked do
get do
error! "You broke it! Yes, you!", 403
end
end
end
Run Code Online (Sandbox Code Playgroud)