2013-02-02 13 views
23

Vorrei limitare le richieste a tutti i controller API di essere reindirizzati al percorso JSON. Vorrei utilizzare un reindirizzamento poiché anche l'URL dovrebbe cambiare in base alla risposta.
Un'opzione consisterebbe nell'utilizzare un before_filter che reindirizza la richiesta alla stessa azione ma impone il formato JSON. L'esempio non funziona ancora!Rails: Limita le richieste API al formato JSON

# base_controller.rb 
class Api::V1::BaseController < InheritedResources::Base 
    before_filter :force_response_format 
    respond_to :json 
    def force_response_format 
    redirect_to, params[:format] = :json 
    end 
end 

Un'altra opzione sarebbe quella di limitare il formato nelle impostazioni dei percorsi.

# routes.rb 
MyApp::Application.routes.draw do 
    namespace :api, defaults: { format: 'json' } do 
    namespace :v1 do 
     resources :posts 
    end 
    end 
end 

voglio tutte le richieste di finire come una richiesta JSON:

http://localhost:3000/api/v1/posts 
http://localhost:3000/api/v1/posts.html 
http://localhost:3000/api/v1/posts.xml 
http://localhost:3000/api/v1/posts.json 
... 

Quale strategia mi consiglia?

risposta

5

Seconda opzione, utilizzando il formato percorsi. Se un utente richiede esplicitamente un formato XML, non dovrebbe ricevere una risposta JSON. Dovrebbe ricevere un messaggio che dice che questo URL non risponde al formato XML, o 404.

A proposito, sarebbe piuttosto facile rispondere a tutto ciò che è ciò che dovresti fare secondo me.

class FooController 
    respond_to :xml, :json 
    def show 
    @bar = Bar.find(params[:id]) 
    respond_with(@bar) 
    end 
end 
+0

+1 per l'inizio del commento. L'aggiunta di un formato non è così facile nella mia esperienza, sebbene Rails lo renda facile da implementare. Il progettista dell'API deve ancora riflettere su cosa significa supportare un formato aggiuntivo, con tutte le implicazioni. –

19

L'impostazione di un valore predefinito nei percorsi non trasforma tutte le richieste in una richiesta JSON.

quello che vuoi è fare in modo che qualsiasi cosa tu stia rendering è una risposta JSON

È praticamente avuto nella prima opzione, tranne quello che devi fare questo

before_filter :set_default_response_format 

private 
    def set_default_response_format 
    request.format = :json 
    end 

che sarebbe andato sotto il tuo controller API di base in modo che quando arriva alla tua azione reale il formato sarà sempre JSON.

+0

L'impostazione 'request.format' in': json' risolve il problema che tutte le risposte restituiscono JSON. Tuttavia, non modifica l'URL nella barra degli indirizzi. – JJD

+0

Se stai facendo un'API perché dovresti scrivere l'URL nella barra degli indirizzi? Nota che fare un reindirizzamento restituirebbe uno stato di 300 e probabilmente non è il più efficiente, comunque non citarlo. –

+0

Detto questo, consiglieresti comunque di riscrivere il formato della richiesta su JSON in ogni caso? Un'altra opzione sarebbe quella di restituire alcuni stati HTTP come mathieugagne e tu hai menzionato. – JJD

16

Se si desidera restituire un 404, o di sollevare un errore di RouteNotFound se il formato non è :json, vorrei aggiungere un vincolo di percorso come questo:

Richiede formato JSON:

# routes.rb 
MyApp::Application.routes.draw do 
    namespace :api, constraints: { format: 'json' } do 
    namespace :v1 do 
     resources :posts 
    end 
    end 
end 

Maggiori informazioni può essere trovato qui: http://edgeguides.rubyonrails.org/routing.html#request-based-constraints

+0

Direi che un 406 è una risposta più accurata in questo caso. Qualche idea per cui questo approccio restituisce un 404? – asymmetric

Problemi correlati