Development

Railsで request.body を触るのは避けたほうがいいかも

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
標準