API等を実装していて create アクションなどで以下のように json payload をパースするケースがありました。
def create
payload = JSON.parse(request.body.string)
...
end
開発中だとこれでも問題ないのですが、本番環境などで unicorn を使っていると request.body の返すオブジェクトが変わってくるのでエラーしてしまいました。
ググったところこちらの方法が良さそうです。
http://stackoverflow.com/questions/24566423/checking-request-body-in-grape-api
def create
payload = JSON.parse(env["rack.input"])
...
end
ただこれでもテスト環境だと env[“rack.input”] は nil を返すので、テストが落ちてしまいました。
で最終的に落ち着いたのがこれ
def create
payload = JSON.parse(env["rack.input"].try(:read) || request.body.string)
...
end
これでなんとかどの環境でも動くようになりました。
ちなみに JSON.parse が空文字や nil を受け取ると例外を投げるので実際には以下のようにするといいと思います。
def create
payload = parse_json_payload
...
end
private
def parse_json_payload
JSON.parse(env["rack.input"].try(:read) || request.body.string)
rescue => _
nil
end