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 a400 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 notnil
, 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 totrue
).include_parent_namespaces: false
: Excludes parameters declared in parent namespaces (defaults totrue
).