Ever wanted an easy way to validate your API parameters and spit out clean, developer friendly error messages? Ever notice how there's no good way to do that in Rails?
Enter ApeRawr!
ApeRawr is an amalgamation of two awesome gems: Grape and RocketPants. This gem combines the error handling capabilities of RocketPants with the parameter validation of Grape into a single cohesive tool used for making API parameter validation easier. The maintainers of RocketPants and Grape deserve most of the credit for this gem. I just provided the glue.
Add this line to your application's Gemfile:
gem 'ape-rawr'
And then execute:
$ bundle
Or install it yourself as:
$ gem install ape-rawr
You can define validations and coercion options for you parameters using a params block.
params do
requires :id, type: Integer
optional :text, type: String, regexp: /^[a-z]+$/
group :media do
requires :url
end
end
def :create
...
end
When a type is specified an implicit validation is done after the coercion to ensure the output type is the one declared.
Optional parameters can have a default value.
params do
options :color, type: String, default: 'blue'
end
Parameters can be nested using group
. In the above example, this means params[:media][:url]
is required along with params[:id]
.
Validations can also be defined for a specific action.
params :create do
...
end
def create
...
end
class AlphaNumeric < Grape::Validations::Validator
def validate_param!(attr_name, params)
unless params[attr_name] =~ /^[[:alnum:]]+$/
error!(:alpha_numeric_error, :attribute => attr_name)
end
end
end
params do
requires :text, alpha_numeric: true
end
You can also create custom classes that take parameters.
class Length < Grape::Validations::SingleOptionValidator
def validate_param!(attr_name, params)
unless params[attr_name].length <= @option
error!(:length_error, :attribute => attr_name, :expected_length => @option)
end
end
end
params do
requires :text, length: 140
end
One of the built in features of ApeRawr is the ability to handle rescuing / controlling exceptions and more importantly to handle mapping exceptions to names, messages and error codes.
This comes in useful when you wish to automatically convert exceptions such as ActiveRecord::RecordNotFound
(Note: This case is handled already) to a structured bit of data in the response. Namely, it makes it trivial to generate objects that follow the JSON structure of:
{
"error": "standard_error_name",
"error_description": "A translated error message describing what happened."
}
It also adds a facilities to make it easy to add extra information to the response.
ApeRawr will also attempt to convert all errors in the controller, defaulting to the "system"
exception name and message as the error description. We also provide a registry to allow throwing exception from their symbolic name like so:
error! :not_found
In the controller.
Out of the box, the following exceptions come pre-registered and setup. For each of them, you can either use the error form (`error! :error_key) or you can raise an instance of the exception class like normal.
Error Key | Exception Class | HTTP Status | Description |
---|---|---|---|
:throttled |
ApeRawr::Throttled |
503 Unavailable |
The user has hit an api throttled error. |
:unauthenticated |
ApeRawr::Unauthenticated |
401 Unauthorized |
The user doesn't have valid authentication details. |
:invalid_version |
ApeRawr::Invalidversion |
404 Not Found |
An invalid API version was specified. |
:not_implemented |
ApeRawr::NotImplemented |
503 Unavailable |
The specified endpoint is not yet implemented. |
:not_found |
ApeRawr::NotFound |
404 Not Found |
The given resource could not be found. |
:invalid_resource |
ApeRawr::InvalidResource |
422 Unprocessable Entity |
The given resource was invalid. |
:bad_request |
ApeRawr::BadRequest |
400 Bad Request |
The given request was not as expected. |
:conflict |
ApeRawr::Conflict |
409 Conflict |
The resource was a conflict with the existing version. |
:forbidden |
ApeRawr::Forbidden |
403 Forbidden |
The requested action was forbidden. |
:presence |
ApeRawr::BadRequest |
400 Bad Request |
missing parameter: %{attribute} |
:coerce |
ApeRawr::BadRequest |
400 Bad Request |
invalid parameter: %{attribute} |
:regexp |
ApeRawr::BadRequest |
400 Bad Request |
invalid parameter: %{attribute} |
Note that error also excepts a Hash of contextual options, many which will be passed through to the Rails I18N subsystem. E.g:
error! :throttled, :max_per_hour => 100
Will look up the translation ape_rawr.errors.throttled
in your I18N files, and call them with :max_per_hour
as an argument.
Finally, You can use this to also pass custom values to include in the response, e.g:
error! :throttled, :metadata => {:code => 123}
Will return something similar to:
{
"error": "throttled",
"error_description": "The example error message goes here",
"code": 123
}
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request