I have a small prototype subclass of Grape::API
as a rack service, and am using Grape::Entity
to present my application's internal objects.
I like the Grape::Entity
DSL, but am having trouble finding out how I should go beyond the default JSON representation, which is too lightweight for our purposes. I have been asked to produce output in "jsend or similar" format: http://labs.omniti.com/labs/jsend
I am not at all sure what nature of change is most in keeping with the Grape framework (I'd like a path-of-least-resistance here). Should I create a custom Grape formatter (I have no idea how to do this), new rack middleware (I have done this in order to log API ins/outs via SysLog - but formatting seems bad as I'd need to parse the body back from JSON to add container level), or change away from Grape::Entity
to e.g. RABL?
Example code ("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
Rackup file ("config.ru")
require File.join(File.dirname(__FILE__), "app")
run MainService
I start it up:
rackup -p 8090
And call it:
curl http://127.0.0.1:8090/api/v2/thing
{"llama_name":"Henry"}
What I'd like to see:
curl http://127.0.0.1:8090/api/v2/thing
{"status":"success","data":{"llama_name":"Henry"}}
Obviously I could just do something like
resource :thing do
get do
thing = Thing.new 'Henry'
{ :status => "success", :data => present( thing, :with => ThingPresenter ) }
end
end
in every route - but that doesn't seem very DRY. I'm looking for something cleaner, and less open to cut&paste errors when this API becomes larger and maintained by the whole team
Weirdly, when I tried { :status => "success", :data => present( thing, :with => ThingPresenter ) }
using grape 0.3.2
, I could not get it to work. The API returned just the value from present
- there is more going on here than I initially thought.