Grnbeagle
Grnbeagle

Reputation: 1761

Rails: creating RESTful web services with XML and JSON

I'm curious about the best practice in creating web services which support both XML and JSON output.

At the moment, my service is very XML oriented (see below), but I want to add JSON support.

Here's one example:

  def create
    render_authentication_error and return if !@user
    render_parameter_not_found_error("item") and return if params[:item].nil?
    render_parameter_not_found_error("name") and return if params[:item][:name].blank?
    @item = Item.new(params[:item])
    begin 
      if [email protected] 
        raise "Item not saved" 
      end 
    rescue 
      render_resource_not_saved_error("Error saving #{@item.name}")
    else 
      render_resource_created(:location => item_path(@item))
    end 
  end

There are helper methods in ApplicationController that renders XML accordingly.

I'm not sure how to go about adding respond_to block here since I need to do validations. Is there a way to retrieve format in a controller outside of respond_to block so that I can output error messages in a given format as well?

respond_to do |format|
  format.html { render :json => @item.to_json }
  format.xml { render :xml => @item }
end 

Let me know if you need any clarification.

UPDATE I suppose I'm looking something similar to respond_with in Rails 3. I'm on Rails 2.3 still.. I wonder if it can be done in 2.3?

UPDATE Inherited Resources seems like what I'm looking for.

Thanks!

Upvotes: 2

Views: 1628

Answers (2)

rmk
rmk

Reputation: 4455

It's a little complicated, but it can be achieved. See here:

http://shifteleven.com/articles/2006/11/26/drying-up-respond_to

Also, maybe you can look at request.format and pass it? I am pretty sure it will have the format requested...

Upvotes: 1

Jesse Wolgamott
Jesse Wolgamott

Reputation: 40277

Replace @person with @item, but there's the idea:

respond_to do |format|
  if @person.save 
    format.html { 
      flash[:notice] = 'Person was successfully created.'
      redirect_to @person 
    }
    format.js { render :json => @person, :status => :created, :location => @person} 
    format.xml  { render :xml => @person, :status => :created, :location => @person }
  else
    format.html { render :partial => "form" }
    format.js { render :json=>@person.errors, :status => :unprocessable_entity }
    format.xml  { render :xml => @person.errors, :status => :unprocessable_entity }
  end
end

Upvotes: 1

Related Questions