I am in the process of expanding my Elixir application and wanted to sanity check some of the patterns which have emerged to see what others think.
I am attempting to layer the structure for composition and clarity, but have fallen into the habit of extracting things into a kind of command pattern.
For example, instead of:
defmodule App.Users do def accept_invitation(invitation, user) do end end
I would have:
defmodule App.Users.AcceptInvitation do def call(invitation, user) do end end
My folder structure would be:
This has allowed me to build more complicated commands into separate modules/namespaces with just the relevant functions for that command instead of having lots of functions in the same module with mixed responsibilities.
I’m on a fence a little, but I can’t see any other way of keeping this clean as my application grows.
I have thought of a potential hybrid approach using
defmodule App.Users do defdelegate accept_invitation(invitation, user), to: App.Users.AcceptInvitation, as: :call def simple_function(user) do end end
Which would allow
App.Users.accept_invitation(user), and allow me to bundle with small, related functions which don’t necessarily need their own module. I like this because it keeps the API simpler from the outside.
Or what about:
defmodule App.Users.Invitation do def accept(invitation, user) do end end
However, I don’t particularly like this as I have quite a few Ecto models and would rather not dump too many functions in them and keep them responsible for schema and validation.
Just trying to figure some patterns which will serve me well going forward. The command modules and single
call functions are working well at the moment (especially having the file structure reflect the commands).