The elixir application that I work with every day is an umbrella with 13 applications.
The root folder contains the Phoenix endpoint and the top-level router, which redirects requests to routers defined in other applications.
This means that the application is not divided into layers (web / business / data), but rather into vertical slices of the domain.
This has improved significantly since the application has grown significantly over the past 12 months.
The biggest thing I had was that Phoenix routers share the leading path from the request when forwarding to other routers, so we created a mount macro for use with the Plug router, which keeps the request path unchanged:
defmodule MyApp.Router do @moduledoc """ Top level routing to each of the sub-systems """ use Plug.Router plug :match plug :dispatch mount "/events/*_", Events.Router mount "/report/*_", Report.Router mount "/stats/*_", Stats.Router mount "/auth/*_", Auth.Router end
and mount:
defmacro mount(path, router, opts \\ []) do quote do @opts unquote(router).init(unquote(opts)) match unquote(path), do: unquote(router).call(var!(conn), @opts) end end
We manage the migration of the entire database in one application for simplicity only, but Ecto Schemas are declared separately in each application.
Here is a project demonstrating some of the concepts.
Mike buhot
source share