class Rack::JSONBodyParser

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']

Constants

CONTENT_TYPE_MATCHERS
DEFAULT_PARSER

Public Class Methods

new( app, verbs: %w[POST PATCH PUT], media: 'application/json', &block ) click to toggle source
   # File lib/rack/contrib/json_body_parser.rb
45 def initialize(
46   app,
47   verbs: %w[POST PATCH PUT],
48   media: 'application/json',
49   &block
50 )
51   @app = app
52   @verbs, @media = verbs, media
53   @matcher = CONTENT_TYPE_MATCHERS.fetch(@media.class)
54   @parser = block || DEFAULT_PARSER
55 end

Public Instance Methods

call(env) click to toggle source
   # File lib/rack/contrib/json_body_parser.rb
57 def call(env)
58   begin
59     if @verbs.include?(env[Rack::REQUEST_METHOD]) &&
60        @matcher.call(@media, env['CONTENT_TYPE'])
61 
62       update_form_hash_with_json_body(env)
63     end
64   rescue JSON::ParserError
65     body = { error: 'Failed to parse body as JSON' }.to_json
66     header = { 'Content-Type' => 'application/json' }
67     return Rack::Response.new(body, 400, header).finish
68   end
69   @app.call(env)
70 end

Private Instance Methods

update_form_hash_with_json_body(env) click to toggle source
   # File lib/rack/contrib/json_body_parser.rb
74 def update_form_hash_with_json_body(env)
75   body = env[Rack::RACK_INPUT]
76   return unless (body_content = body.read) && !body_content.empty?
77 
78   body.rewind # somebody might try to read this stream
79   env.update(
80     Rack::RACK_REQUEST_FORM_HASH => @parser.call(body_content),
81     Rack::RACK_REQUEST_FORM_INPUT => body
82   )
83 end