48

I try to tell rails 3.2 that it should render JSON by default, and kick HTML completely like this:

respond_to :json    

def index
  @clients = Client.all
  respond_with @clients
end

With this syntax, I have to add .json to the URL. How can I achieve it?

Arslan Ali
  • 17,418
  • 8
  • 58
  • 76
trnc
  • 20,581
  • 21
  • 60
  • 98

4 Answers4

91

You can modify your routes.rb files to specify the default format

routes.rb

resources :clients, defaults: {format: :json}

This will modify the default response format for your entire clients_controller

rogeliog
  • 3,632
  • 4
  • 27
  • 26
  • 5
    Can this be added globally for all resources? – shredding Oct 31 '13 at 09:14
  • 5
    To add default format to all resources, declare resources in a `defaults` block: `defaults format: 'json' {resources :clients; resources :products}`. – Tony - Currentuser.io Nov 11 '14 at 21:42
  • 4
    is this compatible with newer rails version ? I add the line you mentiond but it still render HTML. could you please explain me how can I do this sir ? thanks – rafalefighter Mar 24 '15 at 14:33
  • 3
    This is great, you can also apply it to namespaces (and probably scopes, etc). For example `namespace :api, { defaults: { format: :json } } do`. Im currently doing that on Rails 5 – Ryan Nov 20 '16 at 20:21
  • thanks @Ryan, that is what exactly I was looking for – sameera207 May 20 '17 at 00:40
16

This pattern works well if you want to use the same controller actions for both. Make a web version as usual, using :html as the default format. Then, tuck the api under a path and set :json as the default there.

Rails.application.routes.draw do

  resources :products

  scope "/api", defaults: {format: :json} do
    resources :products
  end

end
Mark Swardstrom
  • 17,217
  • 6
  • 62
  • 70
11

If you don't need RESTful responding in your index action then simply render your xml response directly:

def index
  render json: Client.all
end
jdoe
  • 15,665
  • 2
  • 46
  • 48
  • 1
    @Tronic Maybe I didn't understand you correctly. I thought your action `index` shouldn't respond to html at all and you want it to respond to json even w/o .json in your url. – jdoe May 21 '12 at 09:21
  • this is a valuable alternative to @rogeilog 's answer for those who don't want to override the default response for ALL of their controller, but just for a certain action – Don Cheadle Feb 23 '15 at 16:04
1

Extending Mark Swardstrom's answer, if your rails app is an API that always returns JSON responses, you could simply do

Rails.application.routes.draw do
  scope '/', defaults: { format: :json } do
    resources :products
  end
end
Cristiano Mendonça
  • 1,220
  • 1
  • 10
  • 21