2013-06-11 6 views
21

Ich schreibe eine API, und es erhält eine JSON Payload als Anforderungs Körper.Wie wird der JSON-Anfragetext in Sinatra nur einmal analysiert und allen Routen zur Verfügung gestellt?

zur Zeit, um es zu bekommen, ich so etwas wie dies tue:

post '/doSomething' do 
    request.body.rewind 
    request_payload = JSON.parse request.body.read 

    #do something with request_payload 
    body request_payload['someKey'] 
end 

Was weg zu abstrahieren ein guter Weg ist, so dass ich es nicht für jede Route tun müssen? Einige meiner Routen sind komplizierter als diese, und infolgedessen würde der request.body mit diesem Ansatz, den ich vermeiden möchte, mehrmals pro Route neu gelesen und repariert werden.

Gibt es irgendeine Möglichkeit, die request_payload nur auf magische Weise zur Verfügung zu Routen zu machen? Wie folgt aus:

post '/doSomething' do 
    #do something with request_payload, it's already parsed and available 
    body request_payload['someKey'] 
end 

Antwort

46

einen sinatra vor Handler:

before do 
    request.body.rewind 
    @request_payload = JSON.parse request.body.read 
end 

dies ihm die aktuellen Request-Handler aussetzen wird. Wenn Sie möchten, dass es allen Handlern zugänglich gemacht wird, legen Sie es in eine Superklasse und erweitern Sie diese Klasse in Ihren Handlern.

+0

Das war mein erster Instinkt, aber wird diese Arbeit mit Asynchron-sinatra? Ich fürchte, nachfolgende Anfragen könnten es überschreiben, während die vorherigen noch im Flug sind? – lms

+1

Sinatra * sollte eine neue Instanz jeden Handler pro Anfrage * erstellen, so vorausgesetzt, Sie eine Instanz Ebene Variable sollte es in Ordnung sein. Wir verwenden ein ähnliches Schema und haben keine Anzeichen von Wettlaufbedingungen unter Last gesehen. – mcfinnigan

+0

Die 'before' Filter [kann] (http://www.sinatrarb.com/intro.html#Filters) ausgesagt auf Leitwegschemata aber scheinbar nicht HTTP-Methoden. Bummer - dies nur für POSTs zu tun ist ein plausibler Anwendungsfall. – mgold

1

Wie diese Arbeit für sinatra 1.4.5

before do 
    if request.body.size > 0 
    request.body.rewind 
    @params = ActiveSupport::JSON.decode(request.body.read) 
    end 
end 
7

Sie auch Rack-Middleware, es zu analysieren, verwenden können. Siehe https://github.com/rack/rack-contribuse Rack::PostBodyContentTypeParser Gerade wenn Ihre Sinatra Klasse zu initialisieren.

Verwandte Themen