README.md in request_handler-1.3.0 vs README.md in request_handler-2.0.0
- old
+ new
@@ -24,38 +24,55 @@
$ gem install request_handler
## Configuration
+You have to chose a validation engine and configure it globally:
+```ruby
+RequestHandler.configure do |config|
+ config.validation_engine = RequestHandler::Validation::DryEngine
+end
+```
+
+If you want to use the included dry engine you also have to add the dry gems to
+your Gemfile:
+```ruby
+ gem 'dry-validation', '~> 1.0'
+ gem 'dry-types', '~> 1.0'
+```
+Note that only dry >= 1.0 is supported.
+
The default logger and separator can be changed globally:
```ruby
-RequestHandler.configure do
- logger Logger.new(STDERR)
- separator '____'
- validation_engine RequestHandler::Validation::DryEngine
+RequestHandler.configure do |config|
+ config.logger = Logger.new(STDERR)
+ config.separator = '____'
end
```
JSON:API-style error data can be included in validation errors raised by `RequestHandler`.
```ruby
-RequestHandler.configure do
- raise_jsonapi_errors = true # default: false
+RequestHandler.configure do |config|
+ config.raise_jsonapi_errors = true # default: false
end
```
### Validation Engine
-Per default this gem uses the `DryEngine` which relies on dry-validation. All
-examples in this Readme assume you are using this default engine. However
-you can also use the builtin `DefinitionEngine`, which uses [Definition](https://github.com/Goltergaul/definition) as validation library:
+You have to chose a validation engine and configure it globally (see
+configuration section above).
+All examples in this Readme assume you are using the `DryEngine` which relies on
+dry-validation. However you can also use the builtin `DefinitionEngine`, which
+uses [Definition](https://github.com/Goltergaul/definition) as validation
+library:
```ruby
-RequestHandler.configure do
+RequestHandler.configure do |config|
require 'request_handler/validation/definition_engine'
- validation_engine RequestHandler::Validation::DefinitionEngine
+ config.validation_engine = RequestHandler::Validation::DefinitionEngine
end
```
You can also implement your own engine to use any other library, by implementing
the abstract class `RequestHandler::Validation::Engine`
@@ -83,18 +100,17 @@
At the moment there are only "jsonapi" and "json" available for `type`. This
defines if the JsonApiDocumentParser or JsonParser is used.
If nothing is defined, JsonApiDocumentParser will be used by default.
```ruby
-require "dry-validation"
require "request_handler"
class DemoHandler < RequestHandler::Base
options do
page do
default_size 10
max_size 20
- comments do
+ resource :comments do
default_size 20
max_size 100
end
end
@@ -106,38 +122,38 @@
allowed Dry::Types["strict.string"].enum("age", "name")
end
filter do
schema(
- Dry::Validation.Params do
- configure do
- option :foo
+ Class.new(Dry::Validation::Contract) do
+ option :foo
+ params do
+ required(:name).filled(:string)
end
- required(:name).filled(:str?)
end
)
additional_url_filter %i(user_id id)
options(->(_handler, _request) { { foo: "bar" } })
# options({foo: "bar"}) # also works for hash options instead of procs
end
query do
schema(
- Dry::Validation.Params do
- optional(:name).filled(:str?)
+ Dry::Schema.Params do
+ optional(:name).filled(:string)
end
)
end
body do
type :jsonapi
schema(
- Dry::Validation.JSON do
- configure do
- option :foo
+ Class.new(Dry::Validation::Contract) do
+ option :foo
+ json do
+ required(:id).filled(:string)
end
- required(:id).filled(:str?)
end
)
options(->(_handler, _request) { { foo: "bar" } })
# options({foo: "bar"}) # also works for hash options instead of procs
end
@@ -206,23 +222,23 @@
```ruby
class CreateQuestionHandler < RequestHandler::Base
options do
multipart do
- question do
+ resource :question do
required true
type "json"
schema(
- Dry::Validation.JSON do
- required(:id).filled(:str?)
- required(:type).filled(:str?)
- required(:content).filled(:str?)
+ Dry::Schema.JSON do
+ required(:id).filled(:string)
+ required(:type).filled(:string)
+ required(:content).filled(:string)
end
)
end
- file do
+ resource :file do
# no validation necessary
end
end
end
@@ -314,9 +330,131 @@
request.params.merge!(params)
dto = DemoHandler.new(request: request).to_dto
# more code
end
```
+
+## v1 to v2 migration guide
+Multiple breaking changes were introduced with request_handler 2.0. This section
+describes which steps have to be taken in order to migrate from 1.x to 2.0.
+
+### Configure validation engine
+By default the DryEngine was used in 1.0. You now have to explicitly configure
+a validation engine:
+
+```ruby
+RequestHandler.configure do |config|
+ config.validation_engine = RequestHandler::Validation::DryEngine
+end
+```
+
+### Add dry dependency if you use the DryEngine
+Since the DryEngine is not configured by default anymore, the dependency to the
+dry gems could be removed from request_handler. If you use the DryEngine
+simply add the dry-gems to your Gemfile:
+
+```ruby
+gem 'dry-validation', '~> 1.0'
+gem 'dry-types', '~> 1.0'
+```
+Note that only dry >= 1.0 is supported.
+
+### Define custom resources via the `resource` key
+In request_handler 1.x it was possible to define custom resource names like this:
+
+```ruby
+options do
+ fieldsets do
+ allowed do
+ posts schema
+ end
+ end
+end
+```
+
+This was possible in multiple places (`page`, `multipart`, `fieldsets.allowed`).
+Starting with version 2.0 you will have to define those custom resources via the
+`resource` key:
+
+```ruby
+options do
+ fieldsets do
+ allowed do
+ resource :posts, schema
+ end
+ end
+end
+```
+
+### Use dry-* 1.x instead of dry-* 0.x if you use the DryEngine
+Some of the most common required changes are listed here:
+
+* Use `Dry::Schema.Params` instead of `Dry::Validation.Schema`
+* Use `Dry::Schema.JSON` instead of `Dry::Validation.JSON`
+* If you use some more complex validation rules with options like this:
+
+```
+Dry::Validation.Params do
+ configure do
+ option :query_id
+ end
+ required(:id).value(eql?: query_id)
+end
+
+options(->(_parser, request) { { query_id: request.params['id'] } })
+```
+
+please rewrite it using `Dry::Validation::Contract` like this:
+
+```
+Class.new(Dry::Validation::Contract) do
+ option :query_id
+ params do
+ required(:id).value(:string)
+ end
+ rule(:id) do
+ key.failure('invalid id') unless values[:id] == query_id
+ end
+end)
+options(->(_parser, request) { { query_id: request.params['id'] } })
+```
+
+A useful guide for upgrading to dry 1 types, validations and schemas can be
+found [here](https://www.morozov.is/2019/05/31/upgrading-dry-gems.html).
+
+Also please refer to the official docs of
+[dry-schema](https://dry-rb.org/gems/dry-schema) and
+[dry-validation](https://dry-rb.org/gems/dry-validation).
+
+### Remove config inheritance
+It was possible to (partially) overwrite configs defined in a request-handler
+super-class:
+```
+class Parent < RequestHandler::Base
+ options do
+ page do
+ comments do
+ default_size 20
+ end
+ end
+ end
+end
+```
+
+```ruby
+class Child < Parent
+ options do
+ page do
+ comments do
+ default_size 10
+ end
+ end
+ end
+end
+```
+
+Support for this has been fully removed. If you overwrite configs in subclasses
+please remove the inheritance and define the two request-handlers separately.
## Development
After checking out the repo, run `bin/setup` to install dependencies. You can
also run `bin/console` for an interactive prompt that will allow you to experiment.