rails-param-validation 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.gitlab-ci.yml +34 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +63 -0
- data/Rakefile +6 -0
- data/bin/.keep +0 -0
- data/docs/_config.yml +3 -0
- data/docs/annotations.md +62 -0
- data/docs/getting-started.md +32 -0
- data/docs/image/error-screenshot.png +0 -0
- data/docs/index.md +61 -0
- data/docs/main-idea.md +72 -0
- data/docs/openapi.md +39 -0
- data/docs/type-definition.md +178 -0
- data/lib/rails-param-validation/errors/missing_parameter_annotation.rb +9 -0
- data/lib/rails-param-validation/errors/no_matching_factory.rb +9 -0
- data/lib/rails-param-validation/errors/param_validation_failed_error.rb +12 -0
- data/lib/rails-param-validation/errors/type_not_found.rb +9 -0
- data/lib/rails-param-validation/rails/action_definition.rb +66 -0
- data/lib/rails-param-validation/rails/annotation_manager.rb +40 -0
- data/lib/rails-param-validation/rails/config.rb +48 -0
- data/lib/rails-param-validation/rails/extensions/annotation_extension.rb +95 -0
- data/lib/rails-param-validation/rails/extensions/custom_type_extension.rb +13 -0
- data/lib/rails-param-validation/rails/extensions/error.template.html.erb +86 -0
- data/lib/rails-param-validation/rails/extensions/validation_extension.rb +105 -0
- data/lib/rails-param-validation/rails/helper.rb +9 -0
- data/lib/rails-param-validation/rails/openapi/openapi.rb +128 -0
- data/lib/rails-param-validation/rails/openapi/routing_helper.rb +40 -0
- data/lib/rails-param-validation/rails/rails.rb +31 -0
- data/lib/rails-param-validation/rails/tasks/openapi.rake +32 -0
- data/lib/rails-param-validation/types/types.rb +100 -0
- data/lib/rails-param-validation/validator.rb +51 -0
- data/lib/rails-param-validation/validator_factory.rb +37 -0
- data/lib/rails-param-validation/validators/alternatives.rb +42 -0
- data/lib/rails-param-validation/validators/array.rb +49 -0
- data/lib/rails-param-validation/validators/boolean.rb +38 -0
- data/lib/rails-param-validation/validators/constant.rb +38 -0
- data/lib/rails-param-validation/validators/custom_type.rb +28 -0
- data/lib/rails-param-validation/validators/date.rb +39 -0
- data/lib/rails-param-validation/validators/datetime.rb +39 -0
- data/lib/rails-param-validation/validators/float.rb +39 -0
- data/lib/rails-param-validation/validators/hash.rb +52 -0
- data/lib/rails-param-validation/validators/integer.rb +39 -0
- data/lib/rails-param-validation/validators/object.rb +63 -0
- data/lib/rails-param-validation/validators/optional.rb +44 -0
- data/lib/rails-param-validation/validators/regex.rb +37 -0
- data/lib/rails-param-validation/validators/string.rb +31 -0
- data/lib/rails-param-validation/validators/uuid.rb +39 -0
- data/lib/rails-param-validation/version.rb +3 -0
- data/lib/rails-param-validation.rb +42 -0
- data/rails-param-validation.gemspec +33 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 78a64263517a4c6d2d0c0e649cc7a3e4708f4ed1abb96beffb8a52b2acc2f8a0
|
4
|
+
data.tar.gz: dfd6039f8ce21dd31c7f96a93daf9c6b10a490107a4f96be6ceaa33f26e1a7fd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c4862edac9546192dddce87b4d0e846443611db3426ad4b91eb5c3827ddbc72cc7e283dfef1f3ed624ee18fcce52db21a4aa04b5ef359dcf85ea5f707dba5caf
|
7
|
+
data.tar.gz: d0606f8d37a4f2bf9e822c410779be3efbefec1e81c505179d3ecc26780202c0961e6f412bd1d4503a354d5b6c8395dd14ba6027f35840783574ad1a75bd642a
|
data/.gitignore
ADDED
data/.gitlab-ci.yml
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
test:2.3:
|
2
|
+
image: ruby:2.3
|
3
|
+
script:
|
4
|
+
- bundle install && rake spec
|
5
|
+
|
6
|
+
test:2.4:
|
7
|
+
image: ruby:2.4
|
8
|
+
script:
|
9
|
+
- bundle install && rake spec
|
10
|
+
|
11
|
+
test:2.5:
|
12
|
+
image: ruby:2.5
|
13
|
+
script:
|
14
|
+
- bundle install && rake spec
|
15
|
+
|
16
|
+
test:2.6:
|
17
|
+
image: ruby:2.6
|
18
|
+
script:
|
19
|
+
- bundle install && rake spec
|
20
|
+
|
21
|
+
test:2.7:
|
22
|
+
image: ruby:2.7
|
23
|
+
script:
|
24
|
+
- bundle install && rake spec
|
25
|
+
|
26
|
+
test:jruby9.2:
|
27
|
+
image: jruby:9.2
|
28
|
+
script:
|
29
|
+
- bundle install && rake spec
|
30
|
+
|
31
|
+
test:jruby9.1:
|
32
|
+
image: jruby:9.1
|
33
|
+
script:
|
34
|
+
- bundle install && rake spec
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 Oskar Kirmis
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# RailsParamValidation
|
2
|
+
|
3
|
+
[![pipeline status](https://git.iftrue.de/okirmis/rails-param-validation/badges/master/pipeline.svg)](https://git.iftrue.de/okirmis/rails-param-validation/commits/master)
|
4
|
+
|
5
|
+
This gem provides parameter validation for Rails using a declarative parameter definition and makes the automatic validation of complex parameters very easy. It also supports an export of the definition as an OpenAPI document.
|
6
|
+
|
7
|
+
* [Why this gem?](./docs/main-idea.md)
|
8
|
+
* [Getting started](./docs/getting-started.md)
|
9
|
+
* [Annotations](./docs/annotations.md)
|
10
|
+
* [How to specify types](./docs/type-definition.md)
|
11
|
+
* [OpenAPI Export](./docs/openapi.md)
|
12
|
+
|
13
|
+
## Quick Example
|
14
|
+
|
15
|
+
Let's take a look at a very simple example: a controller with a sample action, which gets a list of floats, rounds them to the nearest integer and returns it in a json encoded form.
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
class ExampleController
|
19
|
+
desc "Show the functionality of this gem"
|
20
|
+
|
21
|
+
action "Round float values" do
|
22
|
+
# Expect a parameter with the name "values" which contains an array of floats
|
23
|
+
query_param :values, ArrayType(Float), "Values to round"
|
24
|
+
# Document the response of http status 200, which is an array of integers
|
25
|
+
response 200, :success, ArrayType(Integer), "Rounded values response"
|
26
|
+
end
|
27
|
+
def sample_action
|
28
|
+
render json: params[:values].map(&:round)
|
29
|
+
end
|
30
|
+
|
31
|
+
# We assume GET /round to be mapped to this action
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
Sending a valid request, the parameters are validated and casted correctly and we get the response one would expect:
|
36
|
+
|
37
|
+
```
|
38
|
+
$ curl -H "Accept: application/json" "http://localhost:3000/round?values[]=1.5&values[]=2.0&values[]=-0.777"
|
39
|
+
[2,2,-1]
|
40
|
+
```
|
41
|
+
|
42
|
+
When a request with invalid parameters is sent, we get an error response which also describes the error.
|
43
|
+
|
44
|
+
```
|
45
|
+
$ curl -H "Accept: application/json" "http://localhost:3000/round?values[]=1.5&values[]=2.0&values[]=XYZ"
|
46
|
+
{"status":"fail","errors":[{"path":"values/2","message":"Expected a float"}]}
|
47
|
+
```
|
48
|
+
|
49
|
+
## Installation
|
50
|
+
|
51
|
+
Add this line to your application's Gemfile:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
gem 'rails-param-validation'
|
55
|
+
```
|
56
|
+
|
57
|
+
And then execute:
|
58
|
+
|
59
|
+
$ bundle install
|
60
|
+
|
61
|
+
Or install it yourself as:
|
62
|
+
|
63
|
+
$ gem install rails-param-validator
|
data/Rakefile
ADDED
data/bin/.keep
ADDED
File without changes
|
data/docs/_config.yml
ADDED
data/docs/annotations.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Annotations
|
2
|
+
|
3
|
+
## Controller annotations
|
4
|
+
|
5
|
+
**desc**
|
6
|
+
|
7
|
+
Define a description for the controller that is later used in the OpenAPI export.
|
8
|
+
|
9
|
+
## Action annotations
|
10
|
+
|
11
|
+
All of the following annotations have to be placed **above** the action definition and must be used within an `action` block like this:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
action "Return a random number" do
|
15
|
+
query_param :min, Optional(Float, 0.0), 'Minimum value'
|
16
|
+
query_param :max, Optional(Float, 1.0), 'Maximum value'
|
17
|
+
|
18
|
+
response 200, { value: Float }, 'Random value response'
|
19
|
+
end
|
20
|
+
def random_value
|
21
|
+
render json: { value: Random.rand(params[:min]..params[:max]) }
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
**query_param**
|
26
|
+
|
27
|
+
Parameter passed via query string, e.g. `http://localhost/my_action?parameter=value`. The first value is the parameter name (which must be a symbol), the second is the [type definition](./docs/type-definition.md). The last (optional) parameter to this call is the description.
|
28
|
+
|
29
|
+
**path_param**
|
30
|
+
|
31
|
+
Parameter passed as part of the actions route, e.g. `http://localhost/my_action/value` where the route definition is something like `get '/my_action/:parameter, to: 'my_controller#my_action'`. The first value is the parameter name (which must be a symbol), the second is the [type definition](./docs/type-definition.md). The last (optional) parameter to this call is the description.
|
32
|
+
|
33
|
+
**body_param**
|
34
|
+
|
35
|
+
Parameter as part of a JSON body in a POST/PUT/PATCH operation. The first value is the parameter name (which must be a symbol) as the JSON body must be a JSON object which has a key named like the parameter. The second parameter is the [type definition](./docs/type-definition.md). The last (optional) parameter to this call is the description.
|
36
|
+
|
37
|
+
Example body:
|
38
|
+
|
39
|
+
```json
|
40
|
+
{
|
41
|
+
"min": 1.3,
|
42
|
+
"max": 3.7
|
43
|
+
}
|
44
|
+
```
|
45
|
+
|
46
|
+
This body contains two parameters which have to be documented separately, e.g. like this:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
action do
|
50
|
+
body_param :min, Optional(Float, 0.0), 'Minimum value'
|
51
|
+
body_param :max, Optional(Float, 1.0), 'Maximum value'
|
52
|
+
end
|
53
|
+
# ...
|
54
|
+
```
|
55
|
+
|
56
|
+
**response**
|
57
|
+
|
58
|
+
The response annotation defines the possible responses the action can generate, where the first parameter is the HTTP status code, the second is the [type definition](./docs/type-definition.md). The last (optional) parameter to this call is the description.
|
59
|
+
|
60
|
+
**accept_all_params**
|
61
|
+
|
62
|
+
To disable parameter validation, an action can be annotated with the `accept_all_params` annotation.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Getting started
|
2
|
+
|
3
|
+
To get started with this gem, first include it into your Rails application by adding it to your `Gemfile` ...
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
gem 'rails-param-validation'
|
7
|
+
```
|
8
|
+
|
9
|
+
... and running:
|
10
|
+
```sh
|
11
|
+
$ bundle install
|
12
|
+
```
|
13
|
+
|
14
|
+
Having included the gem, you can start using it right away, e.g. by annotating a controller class:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
class ExampleController
|
18
|
+
desc "Show the functionality of this gem"
|
19
|
+
|
20
|
+
action "Round float values" do
|
21
|
+
# Expect a parameter with the name "values" which contains an array of floats
|
22
|
+
query_param :values, ArrayType(Float), "Values to round"
|
23
|
+
# Document the response of http status 200, which is an array of integers
|
24
|
+
response 200, ArrayType(Integer), "Rounded values response"
|
25
|
+
end
|
26
|
+
def sample_action
|
27
|
+
render json: params[:values].map(&:round)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
The parameters for `sample_action` will be automatically checked against our definition on every request.
|
Binary file
|
data/docs/index.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
[![pipeline status](https://git.iftrue.de/okirmis/rails-param-validation/badges/master/pipeline.svg)](https://git.iftrue.de/okirmis/rails-param-validation/commits/master)
|
2
|
+
|
3
|
+
This gem provides parameter validation for Rails using a declarative parameter definition and makes the automatic validation of complex parameters very easy. It also supports an export of the definition as an OpenAPI document.
|
4
|
+
|
5
|
+
* [Why this gem?](./main-idea.md)
|
6
|
+
* [Getting started](./getting-started.md)
|
7
|
+
* [Annotations](./annotations.md)
|
8
|
+
* [How to specify types](./type-definition.md)
|
9
|
+
* [OpenAPI Export](./openapi.md)
|
10
|
+
|
11
|
+
## Quick Example
|
12
|
+
|
13
|
+
Let's take a look at a very simple example: a controller with a sample action, which gets a list of floats, rounds them to the nearest integer and returns it in a json encoded form.
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class ExampleController
|
17
|
+
desc "Show the functionality of this gem"
|
18
|
+
|
19
|
+
action "Round float values" do
|
20
|
+
# Expect a parameter with the name "values" which contains an array of floats
|
21
|
+
query_param :values, ArrayType(Float), "Values to round"
|
22
|
+
# Document the response of http status 200, which is an array of integers
|
23
|
+
response 200, :success, ArrayType(Integer), "Rounded values response"
|
24
|
+
end
|
25
|
+
def sample_action
|
26
|
+
render json: params[:values].map(&:round)
|
27
|
+
end
|
28
|
+
|
29
|
+
# We assume GET /round to be mapped to this action
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
Sending a valid request, the parameters are validated and casted correctly and we get the response one would expect:
|
34
|
+
|
35
|
+
```
|
36
|
+
$ curl -H "Accept: application/json" "http://localhost:3000/round?values[]=1.5&values[]=2.0&values[]=-0.777"
|
37
|
+
[2,2,-1]
|
38
|
+
```
|
39
|
+
|
40
|
+
When a request with invalid parameters is sent, we get an error response which also describes the error.
|
41
|
+
|
42
|
+
```
|
43
|
+
$ curl -H "Accept: application/json" "http://localhost:3000/round?values[]=1.5&values[]=2.0&values[]=XYZ"
|
44
|
+
{"status":"fail","errors":[{"path":"values/2","message":"Expected a float"}]}
|
45
|
+
```
|
46
|
+
|
47
|
+
## Installation
|
48
|
+
|
49
|
+
Add this line to your application's Gemfile:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
gem 'rails-param-validation'
|
53
|
+
```
|
54
|
+
|
55
|
+
And then execute:
|
56
|
+
|
57
|
+
$ bundle install
|
58
|
+
|
59
|
+
Or install it yourself as:
|
60
|
+
|
61
|
+
$ gem install rails-param-validator
|
data/docs/main-idea.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# What problem does this gem try to solve?
|
2
|
+
|
3
|
+
Let's say we expect a JSON body that contains an array of objects which contain - besides others - an array of timestamps (date-times), e.g.:
|
4
|
+
|
5
|
+
```json
|
6
|
+
[
|
7
|
+
{
|
8
|
+
"type": "maxima",
|
9
|
+
"timestamps": [
|
10
|
+
"2020-03-01T16:49:50+01:00",
|
11
|
+
"2020-02-28T16:50:22+01:00"
|
12
|
+
]
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"type": "minima",
|
16
|
+
"timestamps": [
|
17
|
+
"2020-02-29T16:51:12+01:00"
|
18
|
+
]
|
19
|
+
}
|
20
|
+
]
|
21
|
+
```
|
22
|
+
|
23
|
+
Validating such a request requires a lot of code, involving a lot of `is_a?` statements etc. This is both - annoying from a developer perspective and error prone.
|
24
|
+
|
25
|
+
# How does this gem solve this issue?
|
26
|
+
|
27
|
+
This gem introduces a simple way to annotate controller actions with declarative parameter type annotations. For the example shown above, it would look like this:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
action do
|
31
|
+
body_param :data, ArrayType({ type: [:minima, :maxima], timestamps: ArrayType(DateTime) })
|
32
|
+
end
|
33
|
+
def sample_action
|
34
|
+
render json: { status: :ok }
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
This will check the body parameter `:data` and will convert all string representing the timestamps automatically to `DateTime` objects. If the request does not match the definition, it will render either a JSON or HTML response which nicely describes what parameter does not match and why, e.g.:
|
39
|
+
|
40
|
+
```sh
|
41
|
+
$ curl -X POST -d \
|
42
|
+
'{"data": [{"type": "maxima","timestamps": ["2020-03-01T16:49:50+01:00","2020-02-28T16:50:22+01:00"]},{"type": "minima","timestamps": ["2020-02-29T16:51:12+01:00"]}]}' \
|
43
|
+
-H "Content-Type: application/json" \
|
44
|
+
-H "Accept: application/json" \
|
45
|
+
http://localhost:3000/sample_action
|
46
|
+
```
|
47
|
+
|
48
|
+
returns `{"status": "ok"}`. But if we send an invalid value, we get a different response:
|
49
|
+
|
50
|
+
```sh
|
51
|
+
$ curl -X POST -d \
|
52
|
+
'{"data": [{"type": "maxima","timestamps": ["abc","2020-02-28T16:50:22+01:00"]},{"type": "minima","timestamps": ["2020-02-29T16:51:12+01:00"]}]}' \
|
53
|
+
-H "Content-Type: application/json" \
|
54
|
+
-H "Accept: application/json" \
|
55
|
+
http://localhost:3000/home
|
56
|
+
```
|
57
|
+
the server will answer:
|
58
|
+
```json
|
59
|
+
{
|
60
|
+
"errors": [
|
61
|
+
{
|
62
|
+
"message": "Expected a date-time",
|
63
|
+
"path": "data/0/timestamps/0"
|
64
|
+
}
|
65
|
+
],
|
66
|
+
"status": "fail"
|
67
|
+
}
|
68
|
+
```
|
69
|
+
|
70
|
+
If we do not request `application/json`, we get an HTML response which looks like this:
|
71
|
+
|
72
|
+
![alt text](./image/error-screenshot.png)
|
data/docs/openapi.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# OpenAPI Export
|
2
|
+
|
3
|
+
When annotating the controller actions with parameter and response types, you get an [OpenAPI](https://www.openapis.org/) 3.0 export for free.
|
4
|
+
|
5
|
+
## Export task
|
6
|
+
|
7
|
+
When included in a Rails application, this gem automatically adds a rake task with the name `openapi:export`. It exports the OpenAPI definition in YAML format to the applications root directory (filename: `openapi.yaml`).
|
8
|
+
|
9
|
+
```sh
|
10
|
+
$ rake openapi:export
|
11
|
+
Writing <your_apps_dir>/openapi.yaml... done.
|
12
|
+
```
|
13
|
+
|
14
|
+
## Configuration
|
15
|
+
|
16
|
+
An OpenAPI document contains some meta data about the API. By default, the following default values are assumed:
|
17
|
+
|
18
|
+
| Property | Default | Description |
|
19
|
+
|---|---|---|
|
20
|
+
| `info.version` | `1.0` | API version |
|
21
|
+
| `info.title` | Application module name | Name or title of the API |
|
22
|
+
| `info.description` | Application module name + `" application"` | The API's brief description |
|
23
|
+
| `info.url` | `http://localhost:3000` | The base URL of the API, all specified paths are relative to that |
|
24
|
+
|
25
|
+
These properties can be configured, e.g. in the `application.rb`, using:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
# ...
|
29
|
+
module MyApp
|
30
|
+
class Application < Rails::Application
|
31
|
+
RailsParamValidation.openapi.title = "My App's API"
|
32
|
+
RailsParamValidation.openapi.description = 'This is an awesome API to interact with my App'
|
33
|
+
RailsParamValidation.openapi.version = '2.0'
|
34
|
+
RailsParamValidation.openapi.url = 'https://api.myapp.com'
|
35
|
+
|
36
|
+
# ...
|
37
|
+
end
|
38
|
+
end
|
39
|
+
```
|
@@ -0,0 +1,178 @@
|
|
1
|
+
# Type definition
|
2
|
+
|
3
|
+
This gem provides declarative type checking. This part of the documentation will explain, how types are declared. Some types support inner types (e.g. arrays), so the definition can be nested.
|
4
|
+
|
5
|
+
* [Constants](#type-constant)
|
6
|
+
* [Alternatives](#type-alternatives)
|
7
|
+
* [String](#type-string)
|
8
|
+
* [Integer](#type-integer)
|
9
|
+
* [Float](#type-float)
|
10
|
+
* [Boolean](#type-boolean)
|
11
|
+
* [UUID (v4)](#type-uuid)
|
12
|
+
* [RegEx Pattern](#type-regex)
|
13
|
+
* [Date & DateTime](#type-date-time)
|
14
|
+
* [Optional Values](#type-optional)
|
15
|
+
* [Array](#type-array)
|
16
|
+
* [Object](#type-object)
|
17
|
+
* [Hash](#type-hash)
|
18
|
+
|
19
|
+
<a name="type-constant"></a>
|
20
|
+
### Constants
|
21
|
+
|
22
|
+
Accepts exactly the defined value, if its string representation is identical. This is especially useful in combination with alternatives.
|
23
|
+
|
24
|
+
Example:
|
25
|
+
```ruby
|
26
|
+
query_param :accept_terms, true, "The user's consent to the terms of service"
|
27
|
+
```
|
28
|
+
|
29
|
+
This would accept the values `"true"` or `true` and reject all others.
|
30
|
+
|
31
|
+
<a name="type-alternatives"></a>
|
32
|
+
### Alternatives
|
33
|
+
|
34
|
+
Accepts values that match at least one of the definitions.
|
35
|
+
|
36
|
+
Example:
|
37
|
+
```ruby
|
38
|
+
query_param :gender, [:male, :female, :other], "User's gender"
|
39
|
+
query_param :date_or_timestamp, [DateTime, Integer], "Modification date"
|
40
|
+
```
|
41
|
+
|
42
|
+
The first example will match any of the values `"male"`, `"female"`, `"other"`.
|
43
|
+
|
44
|
+
The second example will match any iso formatted date time string or a timestamp (e.g. seconds since 1970-01-01).
|
45
|
+
|
46
|
+
<a name="type-string"></a>
|
47
|
+
### String
|
48
|
+
|
49
|
+
Accept any string or type which can be converted to a string, namely: `String`, `Symbol`, `Numeric`, `Boolean`. The value will be automatically converted to a string.
|
50
|
+
|
51
|
+
Example:
|
52
|
+
```ruby
|
53
|
+
query_param :name, String, "The user's name"
|
54
|
+
```
|
55
|
+
|
56
|
+
<a name="type-integer"></a>
|
57
|
+
### Integer
|
58
|
+
|
59
|
+
Accepts an integer or a string which represents an integer. If a string is passed, which cannot be parsed to an integer, the value is rejected. If the string can be converted to an integer, this is done in any case, if the value is accepted, an integer is returned.
|
60
|
+
|
61
|
+
Example:
|
62
|
+
```ruby
|
63
|
+
query_param :year_of_birth, Integer, "The year, the user was born"
|
64
|
+
```
|
65
|
+
|
66
|
+
In this case, `params[:year_of_birth].is_a? Integer` returns `true`.
|
67
|
+
|
68
|
+
|
69
|
+
<a name="type-float"></a>
|
70
|
+
### Float
|
71
|
+
|
72
|
+
Accepts an integer, float or a string which represents a float. If a string is passed, which cannot be parsed to a float, the value is rejected. If the string can be converted to a float, this is done in any case, if the value is accepted, a float is returned. Also integers are converted to floats.
|
73
|
+
|
74
|
+
Example:
|
75
|
+
```ruby
|
76
|
+
query_param :radius, Float, "Search radius"
|
77
|
+
```
|
78
|
+
|
79
|
+
In this case, `params[:radius].is_a? Float` returns `true`.
|
80
|
+
|
81
|
+
|
82
|
+
<a name="type-boolean"></a>
|
83
|
+
### Boolean
|
84
|
+
|
85
|
+
Accepts a float or a string, which represents a boolean (either `"true"` or `"false"`).
|
86
|
+
|
87
|
+
Example:
|
88
|
+
```ruby
|
89
|
+
query_param :radius, Float, "Search radius"
|
90
|
+
```
|
91
|
+
|
92
|
+
In this case, `params[:radius].is_a? Float` returns `true`.
|
93
|
+
|
94
|
+
|
95
|
+
<a name="type-uuid"></a>
|
96
|
+
### Uuid
|
97
|
+
|
98
|
+
Accepts a string or symbol in uuid v4 format. If the string does not match the correct format, it is rejected.
|
99
|
+
|
100
|
+
Example:
|
101
|
+
```ruby
|
102
|
+
query_param :user_id, Uuid, "The user's ID"
|
103
|
+
```
|
104
|
+
|
105
|
+
|
106
|
+
<a name="type-regex"></a>
|
107
|
+
### Regex
|
108
|
+
|
109
|
+
Accepts a string or symbol, that matches a given `RegExp` pattern.
|
110
|
+
|
111
|
+
Example:
|
112
|
+
```ruby
|
113
|
+
query_param :slug, /[a-z][a-z_0-9]+/, "Slug for the article as used in the URL"
|
114
|
+
```
|
115
|
+
|
116
|
+
<a name="type-date-time"></a>
|
117
|
+
### Date & DateTime
|
118
|
+
|
119
|
+
Accept strings that represent valid dates or datetimes, e.g. `"2020-02-28"` (for dates) or `"2020-02-28T12:13:14+01:00"`.
|
120
|
+
|
121
|
+
Example:
|
122
|
+
```ruby
|
123
|
+
query_param :expiration_date, Date, "Date until the article will be available"
|
124
|
+
```
|
125
|
+
|
126
|
+
<a name="type-optional"></a>
|
127
|
+
### Optional Value
|
128
|
+
|
129
|
+
If a value is not passed, define a default value which is returned in this case. It can be used with any inner type. If the value is passed, it is validated. If it does not match, the value is rejected. If it is not specified at all, the default value is used.
|
130
|
+
|
131
|
+
Example:
|
132
|
+
```ruby
|
133
|
+
query_param :public, Optional(Boolean, false), "Will the article be publicly available"
|
134
|
+
query_param :expiration_date, Optional(Date, -> { Date.today + 14.days }), "Date until the article will be available"
|
135
|
+
```
|
136
|
+
|
137
|
+
In the first example, the constant is `false` is returned if no value is specified.
|
138
|
+
|
139
|
+
In the second example, the `Proc` is evaluated whenever no data is passed for the parameter.
|
140
|
+
|
141
|
+
<a name="type-array"></a>
|
142
|
+
### Array
|
143
|
+
|
144
|
+
Accepts a list of values. Every value of the entry has to match the inner type.
|
145
|
+
|
146
|
+
Example:
|
147
|
+
```ruby
|
148
|
+
body_param :tags, ArrayType(String), "Tags to assign to the article"
|
149
|
+
```
|
150
|
+
|
151
|
+
This can be combined with any inner type.
|
152
|
+
|
153
|
+
<a name="type-object"></a>
|
154
|
+
### Object
|
155
|
+
|
156
|
+
Accept an object with a defined list of keys. All properties have to match there definition.
|
157
|
+
|
158
|
+
Example:
|
159
|
+
```ruby
|
160
|
+
body_param :article, {
|
161
|
+
title: String,
|
162
|
+
body: String,
|
163
|
+
expiration_date: Optional(Date, Date.today + 14.days),
|
164
|
+
tags: ArrayType(String)
|
165
|
+
}, "Article to store"
|
166
|
+
```
|
167
|
+
|
168
|
+
<a name="type-hash"></a>
|
169
|
+
### Hash
|
170
|
+
|
171
|
+
Accept an object with arbitrary keys. The values and the keys can be validated against a type definition.
|
172
|
+
|
173
|
+
Example:
|
174
|
+
```ruby
|
175
|
+
body_param :settings, HashType(DateTime, /key_[a-z]/), "User settings"
|
176
|
+
```
|
177
|
+
|
178
|
+
In this case, all keys have to start with `key_` and the rest may only consist of lower case letters. The values have to be date times.
|