{"id":15994700,"url":"https://github.com/aars/rack-bodyparser","last_synced_at":"2025-07-21T11:33:10.964Z","repository":{"id":56890052,"uuid":"55517822","full_name":"aars/rack-bodyparser","owner":"aars","description":"Rack Middleware for parsing request body.","archived":false,"fork":false,"pushed_at":"2017-11-21T12:57:30.000Z","size":25,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-02T20:55:11.489Z","etag":null,"topics":["body-parser","jsonapi","parse","rack","rack-middleware","ruby","sinatra"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aars.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-04-05T15:05:39.000Z","updated_at":"2023-07-11T16:25:03.000Z","dependencies_parsed_at":"2022-08-20T16:00:52.854Z","dependency_job_id":null,"html_url":"https://github.com/aars/rack-bodyparser","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aars/rack-bodyparser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aars%2Frack-bodyparser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aars%2Frack-bodyparser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aars%2Frack-bodyparser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aars%2Frack-bodyparser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aars","download_url":"https://codeload.github.com/aars/rack-bodyparser/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aars%2Frack-bodyparser/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266291874,"owners_count":23906349,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["body-parser","jsonapi","parse","rack","rack-middleware","ruby","sinatra"],"created_at":"2024-10-08T07:09:52.693Z","updated_at":"2025-07-21T11:33:10.938Z","avatar_url":"https://github.com/aars.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rack::BodyParser #\n\nRack middleware for parsing incoming request body per content type.\n\n### Inspiration ###\n\n`Rack::BodyParser` is heavily inspired by \n[Rack::Parser](https://github.com/achiu/rack-parser), \nbut behaves a bit different. See Key Features.\n\n## Key Features; Differences to `Rack::Parser` ##\n\n1. `Rack::BodyParser` only parses the request **body**.\n\n1. `Rack::BodyParser` does not touch or replace the original `params` or `request.params`, and does not mix `params` and body payload. Instead the parsed result is stored in a separate key `parsed_body` in Rack's `env`.\n\n1. (optional) patching of `Rack::Request` with support for custom getter method Parsed result available as `request.parsed_body` with support for custom `request.#{your_key_here}` per parser. Enable with `:patch_request =\u003e true`.\n\n1. (optional) access to headers/env. If your parser `respond_to? :env=`, this setter method will be \ninvoked with Rack's `env` just before running `call` on your parser.\n\n#### Batteries not included ####\n\n`Rack::BodyParser` **does** **not** contain any parsers out of the box.\n\n## Installation ##\n\nAvailable through [RubyGems](https://rubygems.org/gems/rack-bodyparser):\n\n`gem install rack-bodyparser`\n\n## Usage ##\n\nDefine your `:parsers` per [`media-type`](http://www.rubydoc.info/gems/rack/Rack/Request/Helpers#media_type-instance_method), which is the `content-type` without media type parameters;\ne.g., when `content-type` is `text/plain;charset=utf-8`, the media-type is `text/plain`.\n\nParsers configuration accepts a `String` or `Regexp` as media-type key,\nand anything that `respond_to? 'call'` as parser.\n\nSinatra example:\n\n```ruby\n# app.rb\n\nuse Rack::BodyParser, :parsers =\u003e { \n  'application/json' =\u003e proc { |data| JSON.parse data },\n  'application/xml'  =\u003e proc { |data| XML.parse data },\n  /msgpack/          =\u003e proc { |data| Msgpack.parse data }\n}\n\npost '/' do\n  puts env['parsed_body']\nend\n```\n\n### Error Handling ###\n\n`Rack::BodyParser` has one default error handler that can be overridden by \nsetting the 'default' handler. As with parsers, you can use a `String` or\n`Regexp` as media-type key and anything that `respond_to? 'call'` as the\nerror handler. The error handler must accept the two parameters \n`Error` and `type` (the media type).\n\n```ruby\nuse Rack::Parser, :handlers =\u003e {\n  'default' =\u003e proc { |e, type| \n    [400, {}, ['[Rack::BodyParser] Failed to parse %s: %s' % [type, e.to_s]]] \n  },\n  'application/xml' =\u003e proc { [400, {}, 'Error: XML unsupported'] }\n}\n```\n\n__Note__: the error handler rescues exceptions that descend from `StandardError`. \nSee http://www.mikeperham.com/2012/03/03/the-perils-of-rescue-exception/\n\n\n#### Logging ####\n`Rack::BodyParser` will try to `warn` if a `logger` is present.\n\n## Patch Rack::Request ##\n\nSetting up `Rack::BodyParser` with `:patch_request =\u003e true` will add\na `parsed_body` getter method to `Rack::Request`. Parsers can also provide a\n`:rack_request_key` to define a custom key per parser:\n\n```ruby\n\n# gem 'jsonapi_parser'\nrequire 'json/api' # JSONAPI document parser/validator\nmodule Rack::BodyParser::JSONAPI\n  module Parser\n    # This defines the getter key for Rack::Request\n    def self.rack_request_key; :document; end\n\n    def self.call(body)\n      JSON::API.parse(JSON.parse(body))\n    end\n  end\n\n  module Error\n    def self.call(e, type)\n      payload = {\n        errors: {\n          title: 'Failed to parse body as JSONAPI document',\n          detail: e.message\n        }\n      }.to_json\n      [422, {}, [payload]]\n    end\n  end\nend\n\nuse Rack::BodyParser, :patch_request =\u003e true,\n  :parsers  =\u003e { \n    'application/vnd.api+json' =\u003e Rack::BodyParser::JSONAPI::Parser\n  },\n  :handlers =\u003e {\n    'application/vnd.api+json' =\u003e Rack::BodyParser::JSONAPI::Error\n  }\n\npost '/' do\n  # These all output the same\n  puts env['parsed_body']\n  puts request.parsed_body\n  puts request.document\nend\n```\n## Request headers/environment ##\n\nNeed headers or other data from Rack's `env` in your parser? Set up your parser\nwith a setter method, `respond_to? :env=`, and it will be invoked just before running\nthe main `call` method.\n\n```ruby\n\nmodule ThisParserNeedsHeaders\n  def self.env=(env)\n    @env = env\n  end\n\n  def self.call(body)\n    # @env available here for your parsing pleasure.\n  end\nend\n\nuse Rack::BodyParser, :parsers =\u003e { \n  'plain/text' =\u003e ThisParserNeedsHeaders \n}\n```\n\n## Copyright\n\n`Copyright © 2016, 2017 Aaron Heesakkers.`\n\nSee [MIT-LICENSE](https://github.com/aars/rack-bodyparser/blob/master/MIT-LICENSE) for details.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faars%2Frack-bodyparser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faars%2Frack-bodyparser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faars%2Frack-bodyparser/lists"}