Отвечать только на json в rails
В моем приложении rails, которое является только json, я хочу отправить код 406 всякий раз, когда кто-то вызывает мое приложение rails с приемом заголовка, установленным на все, кроме приложения /json. Я также хочу, чтобы он отправил 415, когда я установил тип контента для чего угодно, кроме application/json
У моих контроллеров есть response_to: json на них. Я выполняю только json во всех действиях. Однако как я могу гарантировать, что я верну код ошибки 406/415 для всех вызовов всего, что вызывается для всех других заголовков/типов контента, и с форматом, установленным на все, кроме json.
Eg. Если я мой ресурс - это книги /1, я хочу разрешить
книги /1.json или книги /1 с приложением /json в заголовке accept и типе содержимого
Любые идеи о том, как я могу выполнять эти два действия?
Ответы
Ответ 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