Parameters, Validation, and Coercion

Grape provides a powerful DSL to declare, validate, and coerce request parameters. This ensures that your API endpoints receive clean, predictable data, reducing boilerplate code and improving security.

Accessing Parameters

Request parameters from GET query strings, POST/PUT bodies, and named route segments are all available in the params hash.

get 'statuses/:id' do
  # params[:id] contains the value from the URL
  # params[:sort] would contain the value from /statuses/123?sort=asc
  Status.find(params[:id])
end

Grape automatically parses JSON and XML request bodies if the Content-Type header is set correctly.

Declaring Parameters with params

You can define validations and coercions in a params block. This block describes the expected parameters for an endpoint or a whole namespace.

params do
  requires :id, type: Integer, desc: 'Status ID.'
  optional :text, type: String, regexp: /\A[a-z]+\z/, desc: 'Status text.'
  optional :media, type: Hash do
    requires :url, type: String
  end
end
put ':id' do
  # params[:id] is guaranteed to be an Integer
end

requires vs. optional

  • requires: The parameter must be present. If it's missing, Grape returns a 400 Bad Request error.
  • optional: The parameter is not required.

Default Values

Optional parameters can have a default value.

params do
  optional :color, type: String, default: 'blue'
  # For dynamic defaults, use a lambda
  optional :random_number, type: Integer, default: -> { Random.rand(1..100) }
end

Parameter Coercion and Types

When you specify a type, Grape automatically coerces the incoming parameter to that type.

Supported Types: Integer, Float, BigDecimal, Numeric, Date, DateTime, Time, Boolean, String, Symbol, File, JSON, Array, Set, and Hash.

Custom Types: You can use your own classes as types if they implement a class-level parse method.

class Color
  def self.parse(value)
    # ... logic to parse color ...
  end
end

params do
  requires :color, type: Color
end

Validation

Grape includes a rich set of built-in validators.

  • values: Restricts a parameter to a specific set of values (can be an array, a range, or a proc).

    requires :status, type: Symbol, values: [:active, :inactive]
    requires :latitude, type: Float, values: -90.0..+90.0

  • regexp: Ensures the parameter matches a regular expression.

    requires :email, regexp: /.+@.+/

  • allow_blank: false: Ensures a parameter is not nil, an empty string, or whitespace-only.

  • mutually_exclusive, exactly_one_of, at_least_one_of, all_or_none_of: For conditional validations between multiple parameters.
    optional :text_message
    optional :photo_url
    mutually_exclusive :text_message, :photo_url

Custom Validators

You can create your own reusable validators by subclassing Grape::Validations::Validators::Base.

class MyCustomValidator < Grape::Validations::Validators::Base
  def validate_param!(attr_name, params)
    unless params[attr_name] == 'valid'
      raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: 'is not valid!'
    end
  end
end

# In your API:
params do
  requires :custom_field, my_custom_validator: true
end

Nested Parameters

You can declare nested parameters by passing a block to requires or optional and setting the type to Hash or Array.

params do
  requires :user, type: Hash do
    requires :name, type: String
    optional :address, type: Hash do
      requires :city, type: String
    end
  end
end

The declared Helper

The declared helper method is essential for security and robustness. It returns a hash containing only the parameters that have been explicitly defined in the params block, filtering out any unknown or unwanted parameters.

params do
  requires :name, type: String
  optional :age, type: Integer
end
post '/users' do
  # If the request is POST /users?name=John&age=30&admin=true,
  # declared(params) will be { name: 'John', age: 30 }.
  # The `admin` parameter is ignored.
  User.create!(declared(params))
end

declared Options

  • include_missing: false: Excludes parameters that were declared but not present in the request (defaults to true).
  • include_parent_namespaces: false: Excludes parameters declared in parent namespaces (defaults to true).