Подтвердить что ты не робот

Отвечать только на json в rails

В моем приложении rails, которое является только json, я хочу отправить код 406 всякий раз, когда кто-то вызывает мое приложение rails с приемом заголовка, установленным на все, кроме приложения /json. Я также хочу, чтобы он отправил 415, когда я установил тип контента для чего угодно, кроме application/json

У моих контроллеров есть response_to: json на них. Я выполняю только json во всех действиях. Однако как я могу гарантировать, что я верну код ошибки 406/415 для всех вызовов всего, что вызывается для всех других заголовков/типов контента, и с форматом, установленным на все, кроме json.

Eg. Если я мой ресурс - это книги /1, я хочу разрешить книги /1.json или книги /1 с приложением /json в заголовке accept и типе содержимого

Любые идеи о том, как я могу выполнять эти два действия?

4b9b3361

Ответ 1

В принципе, вы можете ограничить свои ответы двумя способами.

Во-первых, для ваших контроллеров есть respond_to. Это будет автоматически запускать 406 Not Acceptable, если будет выполнен запрос для формата, который не определен.

Пример:

class SomeController < ApplicationController
  respond_to :json


  def show
    @record = Record.find params[:id]

    respond_with @record
  end
end

Другим способом было бы добавить before_filter, чтобы проверить формат и соответственно отреагировать.

Пример:

class ApplicationController < ActionController::Base
  before_filter :check_format


  def check_format
    render :nothing => true, :status => 406 unless params[:format] == 'json' || request.headers["Accept"] =~ /json/
  end
end

Ответ 2

Вы можете сделать это с помощью before_filter в ApplicationController

before_filter :ensure_json_request

def ensure_json_request
  return if params[:format] == "json" || request.headers["Accept"] =~ /json/
  render :nothing => true, :status => 406
end

Ответ 3

На рельсах 4.2+ response_to был удален, поэтому, если вы не хотите импортировать полный камень для респондентов только для этого, лучше всего сворачивать самостоятельно. Это то, что я использую в своих рельсах 5 api:

    class ApplicationController < ActionController::API
      before_action :force_json

      private
      def force_json
        # if params[_json] it means request was parsed as json 
        # if body.read.blank? there was no body (GET/DELETE) so content-type was meaningless anyway
        head :not_acceptable unless params['_json'] || request.body.read.blank?
      end
    end