dry-rb / dry-rb/dry-validation

Composable contracts

Open
#593 22 comments 19 reactions 0 assignees View on GitHub
⚠️ experimental ⚠️ feature wip
Dominant language
Ruby
Stars
1.4k
Forks
195
PR merge metrics
No merged PRs in 30d

Description

This feature will allow contracts to be composed of other contracts, optionally mounted at input paths.

## Example

```ruby
# this contract defines its own params and rules, but also uses the
# schema/rules of CustomerContract, and AddressContract on the input at :address
# via the #contract and #path methods
class OrderContract < ApplicationContract
params do
required(:accept_terms).value(:bool)
end

rule(:accept_terms).validate(:acceptance)

contract CustomerContract

path :address do
contract AddressContract
end
end
```

## Implementation

- Initial on branch [composable-contracts](https://github.com/dry-rb/dry-validation/tree/composable-contracts)
- [x] Create a **:composable** extension
- [x] implement new #contract feature in the :composable extension
- [x] Add #path block DSL
- [ ] Rewrite ResultSet as extension to Result
- [ ] Rewrite the [contract/call_spec](https://github.com/dry-rb/dry-validation/blob/master/spec/integration/contract/call_spec.rb) integration test using the desired new syntax
- [ ] Add an example
- [ ] Document the changes in docsite

- Future work
- Decide on exact semantics for merging result values/errors if its unclear
- Ensure it works wrt: concurrency
- Figure out if we should integrate with other extensions in the short term
- Decide on a syntax so contracts can be applied to nested **arrays** of input
- Decide on a syntax so contracts can be conditionally be applied depending on the input
- If consensus that the API is good, remove the :composable extension and rewrite contract and result to include the new functionality by default

## Resources

- Discussion on the [dry-rb forum](https://discourse.dry-rb.org/t/thoughts-on-dry-validation-wrt-composing-validations/904/3)
- [Code spike gist](https://gist.github.com/ianwhite/a32fcd439020ea07ed1fe3243152274f)
- [Pasteable in irb example](https://gist.github.com/ianwhite/918c7ba3487e05b2272a42c154e6b6fb)

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.