{"id":25417352,"url":"https://github.com/neerfri/exon","last_synced_at":"2025-10-31T09:31:07.189Z","repository":{"id":62429266,"uuid":"87920726","full_name":"neerfri/exon","owner":"neerfri","description":"A collection of useful concepts for building data backed applications in Elixir","archived":false,"fork":false,"pushed_at":"2017-05-24T20:52:41.000Z","size":43,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-13T08:46:08.148Z","etag":null,"topics":["elixir","elixir-lang"],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neerfri.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-11T10:22:17.000Z","updated_at":"2017-12-09T19:50:31.000Z","dependencies_parsed_at":"2022-11-01T20:03:11.799Z","dependency_job_id":null,"html_url":"https://github.com/neerfri/exon","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neerfri%2Fexon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neerfri%2Fexon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neerfri%2Fexon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neerfri%2Fexon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neerfri","download_url":"https://codeload.github.com/neerfri/exon/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239120223,"owners_count":19584980,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","elixir-lang"],"created_at":"2025-02-16T17:38:40.373Z","updated_at":"2025-10-31T09:31:06.874Z","avatar_url":"https://github.com/neerfri.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Exon [![hex.pm](http://img.shields.io/hexpm/v/exon.svg?style=flat)](https://hex.pm/packages/exon)\n\nA collection of useful concepts for building data backed applications in Elixir\n\n`Exon` draw inspiration from DDD's approach to domain modeling.\nIt encourages the use of aggregates, commands and events to describe the application's\ndomain.\n\n\n\n## Usage\n\nAdd `Exon` to your `mix.exs` file:\n\n```\ndefp deps do\n  [\n    {:exon, \"~\u003e 0.1.11\"},\n  ]\nend\n```\n\n## Concepts\n\n### Command\n\nA Command is a module function responsible for a specific write operation\nof the application.\n\n### Command Gateway\n\nA CommandGateway is a module responsible for dispatching commands to their respective\naggregate root. A CommandGateway should `use Exon.CommandGateway`.\n\n### Aggregate Root\n\nA module that represents an entity or a group of entities in the domain.\nEvery command is dispatched to a single aggregate root. This makes the aggregate\nroot a transaction boundary for every command in the system.\nAn Aggregate Root should `use Exon.AggregateRoot` which provides the command registration\nmechanism using the `@command` method annotation.\n\n### Event Bus\n\nA module responsible for publishing domain events to it's registered event handlers.\nAn event bus should `use Exon.EventBus` which provides a GenServer based publisher\nand the `add_handler` function to add event handlers.\n\n### Event handler\n\nA module responsible of domain logic that should be executed when a specific domain\nevent is raised.\nAn event handler can handle zero or more domain events.\n\n### Middleware\n\nA module that is registered using `middleware/1` in the command gateway.\nIt's `before_dispatch/2` and `after_dispatch/2` functions will be called before\nand after dispatching the command to the aggregate root.\n\nThe `before_dispatch/2` can be used to change most aspects of the command execution.\nFor example `Exon.Middleware.EctoAggregate` will fetch the correct entity from the\nDB and add it as the first argument for the command method.\n\nThe `after_dispatch/2` can be used to handle changes that should happen after a\nsuccessful or failed command execution. For example `Exon.Middleware.EctoAggregate`\nwill save a changeset in case one is returned from the command.\n\n## Example\n\nSee the code for `TodoApp` under `test/support/todo_app`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneerfri%2Fexon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneerfri%2Fexon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneerfri%2Fexon/lists"}