2013-02-02 16 views
23

Ich möchte Anfragen an alle API-Controller auf die Weiterleitung an den JSON-Pfad beschränken. Ich möchte eine Weiterleitung verwenden, da sich auch die URL entsprechend der Antwort ändern sollte.
Eine Option wäre die Verwendung einer before_filter, die die Anfrage an die gleiche Aktion umleitet, aber das JSON-Format erzwingt. Das Beispiel funktioniert noch nicht!Rails: API-Anfragen auf JSON-Format beschränken

Eine andere Option wäre, das Format in den Routeneinstellungen zu beschränken.

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

Ich möchte alle Anforderung als JSON-Anforderung, um am Ende:

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 
... 

Welche Strategie würden Sie empfehlen?

Antwort

5

Zweite Option, Routenformat verwenden. Wenn ein Benutzer explizit ein XML-Format anfordert, sollte er keine JSON-Antwort erhalten. Er sollte eine Nachricht erhalten, die besagt, dass diese URL nicht auf das XML-Format oder 404 antwortet.

Übrigens wäre es ziemlich einfach, auf alles zu reagieren, was Sie meiner Meinung nach tun sollten.

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

+1 für den Anfang des Kommentars. Das Hinzufügen eines Formats ist meiner Erfahrung nach nicht so einfach, obwohl es mit Rails einfach zu implementieren ist. Der API-Designer muss immer noch darüber nachdenken, was es bedeutet, ein zusätzliches Format mit allen Auswirkungen zu unterstützen. –

19

Wenn Sie einen Standard in Ihren Routen festlegen, werden nicht alle Anfragen in eine JSON-Anfrage umgewandelt.

Was Sie wollen, ist sicher zu stellen, dass was auch immer Sie machen eine JSON-Antwort

Sie ziemlich viel hatte es in der ersten Option, außer Sie diese

before_filter :set_default_response_format 

private 
    def set_default_response_format 
    request.format = :json 
    end 

tun müssen, Das würde gehen unter Ihrem Base-API-Controller, so dass das Format immer JSON ist, wenn es zu Ihrer tatsächlichen Aktion kommt.

+0

Das 'request.format' auf': json' zu setzen löst das Problem, dass alle Antworten JSON zurückgeben. Es ändert jedoch nicht die URL in der Adressleiste. – JJD

+0

Wenn Sie eine API erstellen, warum müssten Sie die URL in die Adressleiste schreiben? Beachten Sie, dass eine Weiterleitung einen Status von 300 zurückgibt und wahrscheinlich nicht der effizienteste, zitieren Sie mich nicht. –

+0

Würden Sie dann empfehlen, das Anfrageformat auf jeden Fall in JSON umzuschreiben? Eine andere Option wäre, einen HTTP-Status als mathieugagne zurückzugeben und Sie erwähnten. – JJD

16

Wenn Sie eine 404 zurückkehren möchten, oder einen RouteNotFound Fehler auslösen, wenn das Format nicht :json ist, würde ich eine Route Einschränkung wie folgt hinzu:

Erfordern JSON-Format:

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

Weitere Informationen finden Sie hier: http://edgeguides.rubyonrails.org/routing.html#request-based-constraints

+0

Ich würde argumentieren, dass eine 406 eine genauere Antwort in diesem Fall ist. Irgendeine Idee, warum dieser Ansatz einen 404 zurückgibt? – asymmetric