Заставить все полученные запросы Content-Type в JSON

Я действительно работаю над API, который использует Rails 4. Я хотел бы установить Content-Type запроса в JSON, если клиент не указывает тип носителя в заголовке Content-Type.

Чтобы получить это поведение, я попытался добавить следующий before_action в мой ApplicationController:

def set_request_default_content_type
  request.format = :json
end

В моем методе RegistrationsController#create у меня есть точка останова, чтобы проверить, все ли работает. Ну, трюк request.format не работает, несмотря на то, что значение установлено на application/json, кажется, что контроллер (или внутренние элементы Rails) не учитывает принятый запрос Content-Type как JSON.

Я выполнил запрос POST со следующим телом (и без Content-Type):

{"user" : {"email":"[email protected]","password":"foobarfoo"}}

Отладка с помощью Pry я вижу, что:

 [2] api(#<V1::RegistrationsController>) _  request.format.to_s
 => "application/json"
 [3] api(#<V1::RegistrationsController>) _  params
 => {
       "action" => "create",
   "controller" => "v1/registrations"
 }

Это означает, что Rails не рассмотрел мой запрос с параметром request.format, настроенным с помощью Mime::JSON, но вместо этого с Mime::ALL и поэтому он не разобрал тело JSON запроса.: (

Ответ 1

class V1::RegistrationsController < ApplicationController
  respond_to :json
end

Создает формат ответа по умолчанию json

Ответ 2

Вы можете определить ответ типа any внутри блока respond_to, который не будет ограничивать ваш контроллер ответом, когда запрос uri заканчивается на .json, он также облегчает вам определение типа ответа явно и будет сохраняться, независимо от типа содержимого запроса, отвечая, как вы пожелаете, например:

respond_to do |format|
  format.any  {render :json => {foo: 'bar'}}
end

Ответ 3

вы можете установить формат по умолчанию с помощью маршрутов: http://guides.rubyonrails.org/routing.html#defining-defaults

resources :registrations, ... defaults: { format: 'json' }

см. также: Как установить формат по умолчанию для маршрута в Rails? Формат-для-а-маршрут-на-рельсы? answertab = активно # закладки сверху


Также может быть интересно:

Rails игнорирует заголовок accept, когда он содержит ",/" или "/", и возвращает HTML (или JS, если это запрос xhr).

Это по дизайну всегда возвращает HTML при обращении к нему из браузера.

Это не соответствует спецификации согласования типа mime, но это был единственный способ обойти старые браузеры с заголовочным заголовком accept. Они принимали заголовок с первым типом mime как image/png или text/xml.