How to generate custom response for REST API with Ruby on Rails? -


i'm implementing rest api in rails 3. allow json , xml response formats.

the default respond_with works fine long 1 wants requested resource returned, e.g.:

def show   respond_with user.find(params[:id]) end  /users/30.xml  <?xml version="1.0" encoding="utf-8"?> <user>   <birthday type="date">2010-01-01</birthday>   <company-name>company</company-name>   <email>email@test.com</email>   <id type="integer">30</id> </user> 

however, following standardized response:

<?xml version="1.0" encoding="utf-8"?> <response>   <status>     <success type="boolean">true</success>   </status>   <result>     <user>       <birthday type="date">2010-01-01</birthday>       <company-name>company</company-name>       <email>email@test.com</email>       <id type="integer">30</id>     </user>   </result> </response> 

how can achieve result?

i tried following, using custom response class

class response    status_codes = {     :success => 0,   }    extend activemodel::naming   include activemodel::serializers::xml   include activemodel::serializers::json    attr_accessor :status   attr_accessor :result    def initialize(result = nil, status_code = :success)     @status = {       :success => (status_code == :success),     }     @result = result   end    def attributes     @attributes ||= { 'status' => nil, 'result' => nil }   end  end 

and redefining respond_with method in applicationcontroller:

  def respond_with_with_api_responder(*resources, &block)     respond_with_without_api_responder(response.new(resources), &block)   end    alias_method_chain :respond_with, :api_responder 

however, not yield intended result:

<?xml version="1.0" encoding="utf-8"?> <response>   <status>     <success type="boolean">true</success>   </status>   <result type="array">     <result>       <birthday type="date">2010-01-01</birthday>       <company-name>company</company-name>       <email>email@test.com</email>       <id type="integer">30</id>     </result>   </result> </response> 

what should <user> again <result>. gets worse when return array result, <result> layer. , if @ json response, looks fine – notice there array [] wrapping user resource.

get /users/30.json  {"response":{"result":[{"user":{"birthday":"2010-01-01","company_name":"company","email":"email@test.com"}}],"status":{"success":true}}} 

any clue going on here? how can desired response format? tried looking writing custom responder class, boiled down rewriting display method within actioncontroller:responder, giving me exact same problems:

  def display(resource, given_options={})     controller.render given_options.merge!(options).merge!(format => response.new(resource))   end 

i believe problem somehow hidden in serialization code of activemodel, can't seem figure out how can wrap resource within container tag , still achieve wrapped resource being serialized correctly.

any thoughts or ideas?

here's did in end:

  1. i got rid of response class.

  2. i added to_json , to_xml methods models:

    [:to_json, :to_xml].each |method_name|   define_method(method_name) |options = {}|     options ||= {}     options[:only] ||= # filtering     super(options)   end end 
  3. i redefined respond_with method in applicationcontroller:

    def api_respond_with(resources, &block)   default_respond_with |format|     format.json { render :json => resources, :skip_types => true, :status => :ok }     format.xml { render :xml => resources, :skip_types => true, :status => :ok }   end end  alias_method :default_respond_with, :respond_with alias_method :respond_with, :api_respond_with 
  4. i wrote custom middleware appropriate methods add desired wrapping:

    class standardizedresponsefilter    def _call(env)     status, headers, response = @app.call(env)     if headers['content-type'].include? 'application/json'       response.body = standardized_json_wrapping(response.body, env)     elsif headers['content-type'].include? 'application/xml'       response.body = standardized_xml_wrapping(response.body, env)     end     [status, headers, response]   end  end 

if knows better approach, feel free leave comment.


Comments

Popular posts from this blog

php - What is the difference between $_SERVER['PATH_INFO'] and $_SERVER['ORIG_PATH_INFO']? -

fortran - Function return type mismatch -

queue - mq_receive: message too long -