The HTTP params parsing module for Crystal 🤓
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

⚠️ This shard requires Crystal master to compile. See installation instructions for Crystal.


Built with Crystal Build status Docs Releases Awesome Patrons count

The HTTP params parsing module for Crysal.

Become Patron


This module adds Params.mapping method to the top-level namespace which turns an Object into a type-safe params container. An initialize(HTTP::Request) method will be added to it, which would parse params from these sources in this particular order, overwriting if needed:

  • Resource params from request.resource_params or .uri_params or .path_params (should be set externally, e.g. by a router)
  • HTTP query params (e.g. "/?id=42")
  • Body depending on "Content-Type" header, currently supporting "application/x-www-form-urlencoded", "multipart/form-data" and "application/json"

The params object will have getters defined as in the mapping, e.g. .id.


Add this to your application's shard.yml:

    github: vladfaust/
    version: ~> 0.1.2

This shard follows Semantic Versioning v2.0.0, so check releases and change the version accordingly.


Call Params.mapping from within an object to turn it into a params container. The object would have got getters defined in accordance with the mapping, i.e. id, name and additional_data in the following example:

require "params"

struct MyParams
    id:   Int32,
    name: String?, # Nilable params

    # Nesting is supported
    # "under_score", "CamelCase", "lowerCamelCase" and "kebab-case"
    # are considered valid upon parsing, however, you should use "under_score"
    # casing in the mapping itself (i.e. in this code).
    # Therefore, "additional_data", "AdditionalData", "additionalData" and "additional-data" is OK
    additional_data: {
      email: String,
      bio:       String | Nil,  # Alternative syntax for nilable params
      tags:      Array(String), # Arrays are supported too

      # Nesting is possible with ∞ levels
      deep: {
        random_numbers: Array(UInt64) | Nil, # Nilable arrays

        admin:   Bool,
        balance: Union(Float64 | Null), # Explicit `null` differs from `nil`
      } | Nil, # Nilable nesting

params = # Initialize it with a HTTP::Request,
                                       # this would trigger the parsing                    # => 42                  # => "John" # =>

The following is an example of a valid HTTP query for this params object, formatted for convenience. You may note that keys are case-insensitive. This structure also applies for "application/x-www-form-urlencoded" and "multipart/form-data" content types:

An example of a valid JSON body would be:

  "id": 42,
  "name": "John",
  "additionalData": {
    "email": "",
    "bio": "foo",
    "tags": ["foo", "bar"],
    "deep": {
      "randomNumbers": [1, 2],
      "admin": true,
      "balance": null

Parsing may eventually raise Params::TypeCastError if an incoming parameter cannot be casted into desired type, or Params::MissingError when a required (i.e. non-nilable) parameter is missing. There is a bunch of other possible errors, see the docs.


crystal spec and you're good to go.


  1. Fork it (
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request