dry-rb / dry-rb/dry-validation
Conditionally Required Fields
- Dominant language
- Ruby
- Stars
- 1.4k
- Forks
- 195
- PR merge metrics
- No merged PRs in 30d
Description
In many REST APIs it's often the case when creating resources, certain fields are required but when updating resources, all fields are optional and only the fields which are provided are updated.
## Examples
For example, the following schema is good for validating user creation.
```ruby
params do
required(:name).filled(str?)
required(:phone_number).filled(:str?)
optional(:metadata).maybe(:hash?)
required(:additional_details).filled(:hash?).schema do
required(:name_km).filled(:str?)
required(:date_of_birth).value(:date, :filled?)
end
end
```
But when updating a user, we need the following schema:
```ruby
params do
optional(:name).filled(str?)
optional(:phone_number).filled(:str?)
optional(:metadata).maybe(:hash?)
optional(:additional_details).filled(:hash?).schema do
optional(:name_km).filled(:str?)
optional(:date_of_birth).value(:date, :filled?)
end
end
```
We don't want to repeat the schema and the rules
My first thought of a possible solution would be something like:
```ruby
option :resource, optional: true
params do
conditionally_required(:name).filled(str?) { resource.present? }
conditionally_required(:phone_number).filled(:str?) { resource.present? }
conditionally_required(:metadata).maybe(:hash?) { resource.present? }
conditionally_required(:additional_details).filled(:hash?) { resource.present? }.schema do
conditionally_required(:name_km).filled(:str?) { resource.present? }
conditionally_required(:date_of_birth).value(:date, :filled?) { resource.present? }
end
end
```
For a PATCH request, the resource could be injected as an external dependency, for a POST request the resource doesn't exist yet so it's not injected.
Contributor guide
Assessment
This issue has not been assessed yet.