PhoenixCommanded
A Commanded code generator for Phoenix applications. This is UNDER CONSTRUCTION, not ready for live use!
The intended audience is new Commanded developers, to get experimental apps up and running quickly.
Experienced Commanded developers can bypass this scaffolding and use the Commanded tooling directly.
The overall direction is to explore how to generate a Commanded app from a data-structure like GraphQL SDL. To guide our work, we'll follow the application described in Event Sourcing with Elixir by Bruno Antunes.
I'll slowly chip away at this, and welcome collaborators and PRs. Chat about Commanded on Gitter or Slack.
Instructions
First, generate an API-only Phoenix app:
$ mix phx.new my_app --no-webpack --no-html
$ cd my_app
Then install this package by adding phoenix_commanded
to your list of
dependencies in my_app/mix.exs
:
def deps do
[
{...},
{:phoenix_commanded, git: "https://github.com/andyl/phoenix_commanded"},
]
end
Then run mix commands to configure your app and generate code.
$ mix deps.get
$ mix phxcom.add.config # add Commanded config w/comspec
$ mix phxcom.add.estore # add Commanded event-stores
$ mix phxcom.gen.code # generate Aggregates, Commands, Events, ...
At this point, you'll have a set of generated directories and source files. You'll have to manually fill out the code stubs, then you can compile and run your application.
$ mix compile # compile the generated code
$ mix ecto.create # create read-store
$ mix ecto.migrate # migrate the read-store
$ mix test # run tests
$ mix phx.server # run server
In another terminal view your API endpoints with $ mix phx.routes
.
Now you can use curl
or your favorite rest-client to interact with your
Phoenix/Commanded application.
Mix Commands
Run $ mix phxcom
to see all generators and generator options.
The Comspec
Phxcom code generation is specified as a configuration option in the file
config/comspec.exs
.
You can view the comspec with the command $ mix phxcom.show.comspec
.
Commanded Elements
Each generated context will contain a standard set of Commanded elements.
Element | Directory | Alias |
---|---|---|
API | / | User |
Aggregate | aggregate/ | A |
Command | command/ | C |
Command Middleware | command/middleware/ | CM |
Command Handler | command/handler/ | CH |
Command Router | command/router/ | CR |
Command Validator | command/validator/ | CV |
Event | event/ | E |
Event Handler | event/handler/ | EH |
Event Projector | event/projector/ | EP |
Read | read/ | R |
Read Schema | read/schema/ | RS |
Read Query | read/query/ | RQ |
Saga (ProcessMgr) | saga/ | S |
Here's how things look on the filesystem...
Here's how the Commanded elements flow together...
Design Notes
Database: We use Postgres for the Event Store, for :dev
, :prod
and :test
Context API: We generate the same API interface as is used by the standard Phoenix/Ecto generators. Your Commanded contexts should be interoperable with a Phoenix-generated context, and should work seamlessly with Phoenix-generated views.