# How to compose params?

**URL:** <https://discourse.hanakai.org/t/how-to-compose-params/1064>\
**Category:** questions\
**Created:** [November 22, 2024, 7:46am UTC](https://discourse.hanakai.org/t/how-to-compose-params/1064 "2024-11-22T07:46:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![vladimirtcats](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/vladimirtcats/32/784_2.png) [@vladimirtcats](https://discourse.hanakai.org/u/vladimirtcats)\
**Post date:** [November 22, 2024, 7:46am UTC](https://discourse.hanakai.org/t/how-to-compose-params/1064/1 "2024-11-22T07:46:43Z")

</div>

Hi everyone

I have a params class

```ruby
module MyApp
  module Actions
    module Document
      module Params
        class Create < Hanami::Action::Params
          params do
            required(:title).filled(:string)
            required(:template).filled(:string)
  
            optional(:type).value(:string)
            optional(:number).value(:string)
          end
        end
      end
    end
  end
end

```

I use this schema in my action

```ruby
params Params::Create

```

I would like to compose in my another action

```ruby
params Params::Create
  optional(:documents).value(:array, min_size?: 1).each do
     schema(Params::Create)
   end
end

```

I have tried several attempts but without success

Also, as I see, It is impossible to pass array without root and validate it

e.g.

using:

```ruby
[
  {}, {}
]

```

instead of

```ruby
{
  documents: []
}

```

---

<div class="post-metadata">

**Author:** ![alassek](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/alassek/32/532_2.png) [@alassek](https://discourse.hanakai.org/u/alassek)\
**Post date:** [November 22, 2024, 8:33pm UTC](https://discourse.hanakai.org/t/how-to-compose-params/1064/2 "2024-11-22T20:33:57Z")

</div>

Use `Dry::Schema` directly instead of `Hanami::Action::Params`. This will allow the usual kind of composition.

`Hanami::Action::Params` is a legacy of Hanami 1.0, and the current plan [is to deprecate it](https://github.com/hanami/controller/issues/455) now that both `Dry::Schema` and `Dry::Validation::Contract` are supported directly.

> [@vladimirtcats](#):
>
> as I see, It is impossible to pass array without root and validate it

I don’t believe top-level arrays have ever worked with `Dry::Schema`, you will need to nest them under a key.

---

<div class="post-metadata">

**Author:** ![vladimirtcats](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/vladimirtcats/32/784_2.png) [@vladimirtcats](https://discourse.hanakai.org/u/vladimirtcats)\
**Post date:** [November 25, 2024, 6:05am UTC](https://discourse.hanakai.org/t/how-to-compose-params/1064/3 "2024-11-25T06:05:22Z")

</div>

Thanks for your response!

---

<div class="post-metadata">

**Author:** ![vladimirtcats](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/vladimirtcats/32/784_2.png) [@vladimirtcats](https://discourse.hanakai.org/u/vladimirtcats)\
**Post date:** [February 6, 2025, 7:31am UTC](https://discourse.hanakai.org/t/how-to-compose-params/1064/4 "2025-02-06T07:31:26Z")

</div>

@alassek  
I only find this way using directly Dry::Schema::Params

```ruby
module MyApp
  module Actions
    module Users
      module Params
        Create = Dry::Schema.Params do
          required(:name).filled(:string)
          required(:email).filled(:string)
        end
      end
    end
  end
end

```

but it seems to me that this syntax is too cumbersome

```ruby
def handle(request, response)
  params_result = Params::Create.call(request.params)

  unless params_result.failure?
    halt 422, { errors: params_result.errors.to_h }.to_json
  end

```

May be short syntax exists

**UPT**  
I have found out how to do this

```ruby
module MyApp
  module Actions
    module Users
      module Contracts
        class Create < Dry::Validation::Contract
          params do 
            required(:name).filled(:string)
            required(:email).filled(:string
          end
        end
      end
    end
  end
end

```

and in controller:

```auto
contract Contracts::Create

```
