Skip to content

Commit bb72584

Browse files
committed
Add documentation for Params extension
Adds documentation for the Params extension to the extensions guide, including: - Overview of input validation with dry-schema - Installation and setup instructions - Basic usage examples showing success and failure cases - Schema class usage for reusing schemas across operations - Integration with custom methods via operate_on - Schema inheritance behavior
1 parent 3dd264f commit bb72584

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

docsite/source/extensions.html.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,115 @@ end
169169
```
170170

171171
⚠️ Warning: The `:requires_new` option for nested transactions is not yet fully supported.
172+
173+
### Params
174+
175+
The `Params` extension adds input validation support to your operations using [dry-schema](https://dry-rb.org/gems/dry-schema/). When a operation is called, the input will be automatically validated against the defined schema before the operation logic executes. If validation fails, the operation returns a `Failure` with detailed error information without executing the operation body.
176+
177+
Make sure you have dry-schema installed:
178+
179+
```ruby
180+
gem "dry-schema"
181+
```
182+
183+
Require and include the extension in your operation class, then define a schema using the `params` class method:
184+
185+
```ruby
186+
require "dry/operation/extensions/params"
187+
188+
class CreateUser < Dry::Operation
189+
include Dry::Operation::Extensions::Params
190+
191+
params do
192+
required(:name).filled(:string)
193+
required(:email).filled(:string)
194+
optional(:age).maybe(:integer)
195+
end
196+
197+
def call(input)
198+
user = step create_user(input)
199+
step notify(user)
200+
user
201+
end
202+
203+
# ...
204+
end
205+
```
206+
207+
When validation succeeds, the operation receives the validated and coerced input:
208+
209+
```ruby
210+
result = CreateUser.new.call(name: "Alice", email: "[email protected]", age: "25")
211+
# => Success(user) with age coerced to integer 25
212+
```
213+
214+
When validation fails, the operation returns a `Failure` tagged with `:invalid_params` and the validation errors, without executing any of the operation's steps:
215+
216+
```ruby
217+
result = CreateUser.new.call(name: "", email: "invalid")
218+
# => Failure[:invalid_params, {name: ["must be filled"]}]
219+
```
220+
221+
#### Using schema classes
222+
223+
You can also pass a pre-defined schema class to `params` instead of a block, which is useful for reusing schemas across multiple operations:
224+
225+
```ruby
226+
UserSchema = Dry::Schema.Params do
227+
required(:name).filled(:string)
228+
required(:email).filled(:string)
229+
optional(:age).maybe(:integer)
230+
end
231+
232+
class CreateUser < Dry::Operation
233+
include Dry::Operation::Extensions::Params
234+
235+
params UserSchema
236+
237+
def call(input)
238+
user = step create_user(input)
239+
step notify(user)
240+
user
241+
end
242+
243+
# ...
244+
end
245+
246+
class UpdateUser < Dry::Operation
247+
include Dry::Operation::Extensions::Params
248+
249+
params UserSchema # Reuse the same schema
250+
251+
def call(input)
252+
# ...
253+
end
254+
end
255+
```
256+
257+
#### Custom wrapped methods
258+
259+
The `params` extension works seamlessly with custom wrapped methods when using `.operate_on`:
260+
261+
```ruby
262+
class ProcessData < Dry::Operation
263+
include Dry::Operation::Extensions::Params
264+
265+
operate_on :process, :transform
266+
267+
params do
268+
required(:value).filled(:string)
269+
end
270+
271+
def process(input)
272+
# input is validated before this executes
273+
end
274+
275+
def transform(input)
276+
# input is validated before this executes
277+
end
278+
end
279+
```
280+
281+
#### Inheritance
282+
283+
Schemas are inherited by subclasses, allowing you to build operation hierarchies with shared validation rules.

0 commit comments

Comments
 (0)