# Command Pattern via TCP

**URL:** <https://forum.elixirforum.com/t/command-pattern-via-tcp/42809>\
**Category:** Questions\
**Tags:** rpc, command-pattern\
**Created:** [October 2, 2021, 6:59pm UTC](https://forum.elixirforum.com/t/command-pattern-via-tcp/42809 "2021-10-02T18:59:20Z")\
**Posts on this page:** 1\
**Showing post:** 9

<div class="post-metadata">

**Author:** ![al2o3cr](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/al2o3cr/32/3457_2.png) [@al2o3cr](https://forum.elixirforum.com/u/al2o3cr)\
**Post date:** [October 3, 2021, 8:31pm UTC](https://forum.elixirforum.com/t/command-pattern-via-tcp/42809/9 "2021-10-03T20:31:42Z")

</div>

Consider the simplest thing that could work: listing the mapping from command to handler atom explicitly.

```elixir
  @handlers %{
    "foo" => Commands.Foo,
    "bar" => Commands.Bar,
    # etc
  }
  defp parse!(_state, [cmd | opts]) do
    case Map.fetch(@handlers, cmd) do
      {:ok, mod} -> {:ok, {mod, opts}}
      :error -> {:ok, {:echo, "#{cmd}: UNKNOWN_COMMAND"}}
    end
  end

```

This approach also has logical extension points for useful things:

- broadening the possible keys of the map to things like `Regex`es would allow for “partial match” commands
- broadening the possible values of the map to `{module, baked_in_opts}` lets one “command module” serve multiple external commands

One downside is that the command → module mapping can get quite long; consider extracting parts of it to functions and combining them at compile-time to reduce clutter.

Worth looking into [`persistent_term`](https://erlang.org/doc/man/persistent_term.html) for storing the map - an Agent still forces every access through a single thread.

---

_[View the full topic](https://forum.elixirforum.com/t/command-pattern-via-tcp/42809)._
