2013-06-11 4 views
21

私はAPIを書いており、リクエスト本体としてJSONペイロードを受け取ります。JSONリクエストボディをSinatraで一度だけ解析してすべてのルートに公開する方法は?

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

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

私は各ルートのためにそれを行う必要はありませんように、この抽象化に良い方法は何ですか:

は現在、それを得るために、私はこのような何かをやっていますか?私のルートの中にはこれよりも複雑なものがあり、その結果、request.bodyはこのアプローチでルートごとに何度も読み返して再解析するので、避けたいものです。

request_payloadを魔法のようにルートに使用できるようにする方法はありますか?このように:

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

答えて

46

ハンドラの前にシナトラを使用します。

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

これは、現在の要求ハンドラにそれを公開します。すべてのハンドラに公開したい場合は、スーパークラスに配置し、そのクラスをハンドラで拡張します。シナトラ1.4.5あなたはまた、それを解析するためにラックミドルウェアを使用することができます

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

これは私の最初の本能でしたが、これはasync-sinatraで動作しますか?以前のものがまだ飛行中である間に、後続の要求がそれを上書きするかもしれないのではないかと思いますか? – lms

+1

Sinatra *はリクエストごとに各ハンドラの新しいインスタンスを作成する必要があります。我々は同様のスキームを採用し、負荷の下で競合状態の証拠を見ていない。 – mcfinnigan

+0

'before'フィルタ[http://www.sinatrarb.com/intro.html#Filters]はルートパターンを前提としていますが、HTTPメソッドではないようです。 Bummer - POSTのみでこれを行うのは、もっともらしいユースケースです。 – mgold

7

のために働いて、このよう

関連する問題