dry-rb / dry-rb/dry-validation

Conditionally Required Fields

Open
#582 9 comments 10 reactions 0 assignees View on GitHub
feature help wanted
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.