web-dev-qa-db-ja.com

Rails:APIリクエストをJSON形式に制限する

すべてのAPIコントローラーへのリクエストをJSONパスにリダイレクトされるように制限したいと思います。レスポンスに応じてURLも変わるのでリダイレクトを使いたい。
1つのオプションは、before_filterリクエストを同じアクションにリダイレクトしますが、JSON形式を強制します。例はまだ動作していません!

# base_controller.rb
class Api::V1::BaseController < InheritedResources::Base
  before_filter :force_response_format
  respond_to :json
  def force_response_format
    redirect_to, params[:format] = :json
  end
end

別のオプションは、ルート設定でフォーマットを制限することです。

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

すべてのリクエストがJSONリクエストとして終了するようにしたい:

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

どの戦略をお勧めしますか?

25
JJD

ルートにデフォルトを設定しても、すべてのリクエストがJSONリクエストに変わるわけではありません。

あなたが望んでいることは、レンダリングしているものがJSON応答であることを確認することです

あなたがこれを行う必要があることを除いて、あなたはほとんど最初のオプションでそれを持っていました

before_filter :set_default_response_format

private
  def set_default_response_format
    request.format = :json
  end

これはベースAPIコントローラーの下に配置されるため、実際のアクションに到達すると、フォーマットは常にJSONになります。

21
Leo Correa

404を返す場合、または形式が:jsonでない場合にRouteNotFoundエラーを発生させる場合は、次のようなルート制約を追加します。

JSON形式が必要:

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

詳細はここにあります: http://edgeguides.rubyonrails.org/routing.html#request-based-constraints

16
PeppyHeppy

ルート形式を使用する2番目のオプション。ユーザーが明示的にXML形式を要求する場合、JSON応答を受け取るべきではありません。このURLはXML形式または404に応答しないというメッセージを受け取るはずです。

ちなみに、私の意見では何をすべきかということに対しては、かなり対応しやすいと思います。

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