Class: Rack::JSONBodyParser
- Inherits:
-
Object
- Object
- Rack::JSONBodyParser
- Defined in:
- lib/rack/contrib/json_body_parser.rb
Overview
A Rack middleware that makes JSON-encoded request bodies available in the request.params hash. By default it parses POST, PATCH, and PUT requests whose media type is application/json
. You can configure it to match any verb or media type via the :verbs
and :media
options.
Examples:
Parse POST and GET requests only
use Rack::JSONBodyParser, verbs: ['POST', 'GET']
Parse POST|PATCH|PUT requests whose content-type matches ‘json’
use Rack::JSONBodyParser, media: /json/
Parse POST requests whose content-type is ‘application/json’ or ‘application/vnd+json’
use Rack::JSONBodyParser, verbs: ['POST'], media: ['application/json', 'application/vnd.api+json']
Defined Under Namespace
Classes: ParserError
Constant Summary collapse
- CONTENT_TYPE_MATCHERS =
{ String => lambda { |option, header| Rack::MediaType.type(header) == option }, Array => lambda { |, header| media_type = Rack::MediaType.type(header) .any? { |opt| media_type == opt } }, Regexp => lambda { if //.respond_to?(:match?) # Use Ruby's fast regex matcher when available ->(option, header) { option.match? header } else # Fall back to the slower matcher for rubies older than 2.4 ->(option, header) { option.match header } end }.call(), }.freeze
- DEFAULT_PARSER =
->(body) { JSON.parse(body, create_additions: false) }
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app, verbs: %w[POST PATCH PUT],, media: 'application/json', &block) ⇒ JSONBodyParser
constructor
A new instance of JSONBodyParser.
Constructor Details
#initialize(app, verbs: %w[POST PATCH PUT],, media: 'application/json', &block) ⇒ JSONBodyParser
Returns a new instance of JSONBodyParser.
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/rack/contrib/json_body_parser.rb', line 45 def initialize( app, verbs: %w[POST PATCH PUT], media: 'application/json', &block ) @app = app @verbs, @media = verbs, media @matcher = CONTENT_TYPE_MATCHERS.fetch(@media.class) @parser = block || DEFAULT_PARSER end |
Instance Method Details
#call(env) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/rack/contrib/json_body_parser.rb', line 57 def call(env) begin if @verbs.include?(env[Rack::REQUEST_METHOD]) && @matcher.call(@media, env['CONTENT_TYPE']) update_form_hash_with_json_body(env) end rescue ParserError body = { error: 'Failed to parse body as JSON' }.to_json header = { 'content-type' => 'application/json' } return Rack::Response.new(body, 400, header).finish end @app.call(env) end |