Предотвратить рубин на рельсах 3 от разбора JSON post
У меня есть метод контроллера в Ruby on Rails 3, который принимает приложение /JSON в качестве типа содержимого. Все это работает так, как ожидалось, но на самом деле я не хочу, чтобы рельсы автоматически анализировали JSON в теле запроса POST. Этот метод действует как шлюз и просто перемещает информацию в очередь и может быть довольно большой. Я не хочу тратить время на обработку данных на @_params, так как это необязательно.
Я считаю, что могу обойти это, установив тип содержимого в заголовке запроса на что-то еще, но я хотел бы быть семантически правильным для HTTP-запросов.
Как отключить эту функцию?
EDIT:
более конкретно, как я могу отредактировать эту функциональность только для этого маршрута?
Ответы
Ответ 1
Параметр синтаксического анализа довольно сильно запекается внутри actionpack lib/action_dispatch/middleware/params_parser.rb
.
Я бы сказал, что лучшее, что вам нужно, это перехватить запрос с помощью Rack, что-то вроде этого.
В lib/raw_json.rb
module Rack
class RawJSON
def initialize(app)
@app = app
end
def call(env)
request = Request.new(env)
if request.content_type =~ /application\/json/i
# test request.path here to limit your processing to particular actions
raw_json = env['rack.input'].read
env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
env['rack.input'] = StringIO.new("raw_json=#{raw_json}")
end
return @app.call(env)
end
end
end
В config.ru
вставьте это перед вызовом run <your app name>::Application
require 'raw_json'
use Rack::RawJSON
Ответ 2
Накладные расходы для разбора JSON с одного запроса относительно низки. У вас есть определенная причина полагать, что обработка JSON способствует любой медлительности в общей обработке?
Если нет, то я бы рекомендовал оставить это как есть до тех пор, пока это не будет идентифицировано как проблема.
Конфигурирование рельсов, чтобы не разобрать, что JSON (либо через какую-либо конфигурацию стойки, либо каким-либо другим способом) создаст только один маршрут в вашем приложении, который не обрабатывается стандартным Rails-способом.
В конце концов, вам может потребоваться некоторая обработка этих данных. Или, может быть, вам нужно будет поставить перед собой какую-то безопасность. Или, может быть, вы захотите зарегистрировать его и связать с пользователем, который его отправил. И когда в этот день вам (или кому-то еще в вашей команде) понадобится войти и внести изменения в эту нестандартную реализацию.
Ведение дел нестандартным способом в реализации Rails может добавить к сложности и времени для поддержки программного обеспечения. Это также общий источник недостатков, поскольку люди менее знакомы с нестандартной обработкой.
Итак, если это не проблема, я бы рекомендовал просто разрешить рельсы обрабатывать JSON, а затем просто передать его через обычный Rails Way.
Ответ 3
Он может быть испечен, но, глядя на код:
module ActionDispatch
class ParamsParser
DEFAULT_PARSERS = {
Mime::XML => :xml_simple,
Mime::JSON => :json
}
def initialize(app, parsers = {})
@app, @parsers = app, DEFAULT_PARSERS.merge(parsers)
end
[ ... ]
strategy = @parsers[mime_type]
Итак, если вы можете отправить хэш на этот инициализатор, вы можете добавить или переопределить значение по умолчанию. Не уверен, что разрешить удаление, но может работать пустой метод парсера.
Parsers ответят здесь: Как инициализировать ActionDispatch:: ParamsParser в Rails 3.1?
Код от actionpack-3.2.8/lib/action_dispatch/middleware/params_parser.rb