# `Skuld.Effects.Command`
[🔗](https://github.com/mccraigmccraig/skuld/blob/main/lib/skuld/effects/command.ex#L1)

Effect for dispatching commands through a unified pipeline.

Commands are structs representing mutations. The handler is a single function
`(command -> computation)` that can route commands however it likes (pattern
matching, map lookup, etc.). The returned computation can use other effects.

## Example

    defmodule MyCommandHandler do
      use Skuld.Syntax

      # Route via pattern matching
      def handle(%CreateTodo{title: title}) do
        comp do
          {:ok, todo} <- EctoPersist.insert(changeset(title))
          _ <- Writer.tell(:events, %TodoCreated{id: todo.id}) |> Comp.then_do(:ok)
          {:ok, todo}
        end
      end

      def handle(%DeleteTodo{id: id}) do
        comp do
          todo <- EctoPersist.get!(Todo, id)
          _ <- EctoPersist.delete(todo)
          _ <- Writer.tell(:events, %TodoDeleted{id: id}) |> Comp.then_do(:ok)
          :ok
        end
      end
    end

    # Use the Command effect
    comp do
      {:ok, todo} <- Command.execute(%CreateTodo{title: "Buy milk"})
      todo
    end
    |> Command.with_handler(&MyCommandHandler.handle/1)
    |> EctoPersist.with_handler(Repo)
    |> Writer.with_handler([], tag: :events, output: &{&1, Enum.reverse(&2)})
    |> Comp.run!()

## Handler Function

The handler function has signature `(command -> computation)`. The returned
computation can use any other effects installed in the pipeline. Routing
is entirely up to the handler - use pattern matching, map lookup, or any
other approach.

# `command_handler`

```elixir
@type command_handler() :: (struct() -&gt; Skuld.Comp.Types.computation())
```

Function that takes a command and returns a computation

# `__handle__`

Install Command handler via catch clause syntax.

Config is the handler function:

    catch
      Command -> &MyHandler.handle/1

# `state_key`

# `with_handler`

```elixir
@spec with_handler(Skuld.Comp.Types.computation(), command_handler()) ::
  Skuld.Comp.Types.computation()
```

Install a command handler for a computation.

The handler is a function `(command -> computation)` that receives the
command and returns a computation. The computation can use any other
effects installed in the pipeline.

## Example

    my_comp
    |> Command.with_handler(&MyHandler.handle/1)
    |> Comp.run!()

    # Or with an anonymous function for dynamic routing:
    my_comp
    |> Command.with_handler(fn cmd ->
      handler = Map.fetch!(handlers, cmd.__struct__)
      handler.(cmd)
    end)
    |> Comp.run!()

---

*Consult [api-reference.md](api-reference.md) for complete listing*
