# Commandex - Make complex actions a first class data type

**URL:** <https://forum.elixirforum.com/t/commandex-make-complex-actions-a-first-class-data-type/28392>\
**Category:** Announcing\
**Tags:** library, commandex\
**Created:** [January 19, 2020, 11:48pm UTC](https://forum.elixirforum.com/t/commandex-make-complex-actions-a-first-class-data-type/28392 "2020-01-19T23:48:51Z")\
**Posts on this page:** 1\
**Showing post:** 5

<div class="post-metadata">

**Author:** ![hpopp](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/hpopp/32/36162_2.png) [@hpopp](https://forum.elixirforum.com/u/hpopp)\
**Post date:** [January 20, 2020, 1:25am UTC](https://forum.elixirforum.com/t/commandex-make-complex-actions-a-first-class-data-type/28392/5 "2020-01-20T01:25:26Z")

</div>

Heh, I’ve thought about it, but it breaks protocols in the way I envision them being used.

Commandex currently lets you write a theoretical phoenix JSON API like this:

```elixir
def register_user(conn, params) do
  params
  |> RegisterUser.run()
  |> Respondable.to_json(conn)
end

def login_user(conn, params) do
  params
  |> LoginUser.run()
  |> Respondable.to_json(conn)
end

```

Where the protocol implementation might look something like:

```elixir
defimpl YourApp.Respondable, for: YourApp.RegisterUser do
  import Phoenix.Controller

  def to_json(%{success: true, data: %{user: user}}, conn) do
    json(conn, %{token: Auth.sign_token(user), user: user})
  end

  def to_json(%{success: false, error: %{user: :already_exists}, conn) do
    conn
    |> put_status(:bad_request)
    |> json(%{error: "Email is already taken."})
  end
end

defimpl YourApp.Respondable, for: YourApp.LoginUser do
  import Phoenix.Controller

  def to_json(%{success: true, data: %{user: user}}, conn) do
    json(conn, %{token: Auth.sign_token(user), user: user})
  end

  def to_json(%{success: false, error: %{login: :unauthorized}, conn) do
    conn
    |> put_status(:unauthorized)
    |> json(%{error: "Invalid password given."})
  end
end

```

The trick is having a consistent naming structure while maintaining the flexibility of different kinds of business logic in protocols. Both of those protocol implementations could call out to a shared `Response.successful_auth_response(conn, user)` function. But they certainly don’t have to, and more importantly, you aren’t sticking all of this logic in the controller.

---

_[View the full topic](https://forum.elixirforum.com/t/commandex-make-complex-actions-a-first-class-data-type/28392)._
