I have a small prototype subtype of Grape::API as a rack service, and I use Grape::Entity to represent the internal objects of my application.
I like DSL Grape::Entity , but it's hard for me to figure out how I should go beyond the default JSON view, which is too easy for our purposes. I was asked to output in jsend or similar format: http://labs.omniti.com/labs/jsend
I'm not at all sure that the nature of the changes is most consistent with the Grape structure (I would like to find the path of least resistance here). Do I have to create my own Grape formatter (I have no idea how to do this), the new rack middleware (I did this to register the API I / O via SysLog), but the formatting seems bad as I will need to parse the body back from JSON to add container level) or change from Grape::Entity to e.g. RABL?
Sample 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 run it:
rackup -p 8090
And call him:
curl http://127.0.0.1:8090/api/v2/thing {"llama_name":"Henry"}
What I would 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 it doesn’t seem very dry. I am looking for something cleaner and less open to cut and remove errors when this API gets bigger and is supported by the whole team.
Oddly enough, when I tried { :status => "success", :data => present( thing, :with => ThingPresenter ) } with grape 0.3.2 , I couldn't get it to work. The API returned only the value from present - more is going on here than I originally thought.