{"id":13879525,"url":"https://github.com/cavalle/banksimplistic","last_synced_at":"2025-04-07T13:06:06.320Z","repository":{"id":1032131,"uuid":"860439","full_name":"cavalle/banksimplistic","owner":"cavalle","description":"Exploring CQRS, Event Sourcing and DDD with Ruby","archived":false,"fork":false,"pushed_at":"2022-06-17T22:10:44.000Z","size":227,"stargazers_count":321,"open_issues_count":1,"forks_count":49,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-03-31T11:04:39.439Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://github.com/cavalle/banksimplistic","language":"Ruby","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/cavalle.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":"2010-08-25T00:16:09.000Z","updated_at":"2025-01-26T18:46:43.000Z","dependencies_parsed_at":"2022-07-06T03:01:24.772Z","dependency_job_id":null,"html_url":"https://github.com/cavalle/banksimplistic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cavalle%2Fbanksimplistic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cavalle%2Fbanksimplistic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cavalle%2Fbanksimplistic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cavalle%2Fbanksimplistic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cavalle","download_url":"https://codeload.github.com/cavalle/banksimplistic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247657276,"owners_count":20974344,"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":[],"created_at":"2024-08-06T08:02:23.885Z","updated_at":"2025-04-07T13:06:06.303Z","avatar_url":"https://github.com/cavalle.png","language":"Ruby","funding_links":[],"categories":["Ruby","Uncategorized"],"sub_categories":["Uncategorized"],"readme":"# BankSimplistic #\n\nBankSimplistic is a sandbox for exploring concepts like Command-Query Responsibility Segregation (CQRS), Event Sourcing and Domain-Driven Design (DDD) with Ruby.\n\nIt's unashamedly based on Mark Nijhof's [Fohjin](http://github.com/MarkNijhof/Fohjin) from which it borrows the domain model of the sample application (a simple bank) as well as the main elements of its architecture. However, while Fohjin is a Windows app written in C#, BankSimplistic is a Ruby on Rails web app.\n\n![Bank](http://dl.dropbox.com/u/645329/bank.jpg)\n\n## Getting started ##\n\nBankSimplistic is a Rails 3.0 application so the first thing to do to get started is to install its dependencies:\n\n    $ bundle install\n  \nFor persistence the app uses [Redis](http://code.google.com/p/redis/). So a Redis server is expected to be installed and running on the standard port. This can be done easily in MacOSX like this:\n\n    $ brew install redis\n    $ redis-server\n\nWith all that set, the test suite should pass by just running:\n\n    $ bundle exec rake\n    \nTo start the servers in development mode you can use [foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html):\n\n    $ foreman start\n    \nThe app is now running at [http://localhost:3000](http://localhost:3000)\n  \n## Directory Structure ##\n\nThere are some differences in the directory structure comparing to a standard Rails app that are worth noting.\n\n**app/models**\n\nActiveRecord is not used, so it's disabled in `environment.rb` and the `models` directory is removed.\n\n**app/controllers**\n\nTraditional `ActiveController` controllers are used here. The interesting part is the segregation of queries and commands. `index` and `show` actions only query the reporting repository, while `create`, `update` and `delete` actions exclusively execute commands.\n\n**app/command_handlers**\n\nCommands executed from controller actions are handled by the classes in this directory. This additional layer abstracts controllers from the domain model which is never exposed to any presentation layer. The responsibility of a Command Handler is finding the proper Aggregate Root and pass the request along.\n\nThe `CommandBus` module, included in `ApplicationController`, takes care of looking up the proper handler for the requested command.\n\n**app/domain**\n\nThis is the equivalent to the missing `app/models` and you'll find the entities and aggregate roots of the domain. As you'd expect, all the domain logic is here. The interesting thing is the use of the _Event Sourcing_ pattern.\n\n`AggregateRoot` and `DomainRepository` modules take care of persisting and publishing events as well as restoring domain objects from them. Only events are persisted in the current implementation (no _Memento_ pattern) and we use Redis for that.\n\n**app/reporting**\n\nReports are subscribed to events from the domain model and update themselves according to those events. That way they are always in sync but totally uncoupled from the domain model. The reporting repository is denormalized and persisted with Redis.\n\n**lib/infrastructure**\n\nInfrastructure libraries. Most of the magic is here. Including implementations of the Event Bus using different technologies (ZeroMQ, AMQP, Redis…)\n\nConfiguration and initialization can be found at `config/initializers/infrastructure.rb` (if you want to try alternative Event Buses you should look here)\n\n**spec/acceptance**\n\nA suite of end-to-end acceptance specs is useful to make sure everything works as expected during the continuous evolution and refactoring of the architecture of the app. A nice pattern that seems to emerge here is that each user story corresponds with a command/event the system is supposed to handle. \n\nWe use Capybara to interact with the app but for setting the context, instead of the usual fixtures or factories, we can  invoke commands.\n\nNo unit specs, everything's way too unstable yet.\n\n## Resources ##\n\n**[CQRS a la Greg Young](http://cre8ivethought.com/blog/2009/11/12/cqrs--la-greg-young/)**\n\nThis post, along with a series of posts linked from the [Fohjin's Readme](http://github.com/MarkNijhof/Fohjin#readme), elaborates on the architecture and patterns used in the Fohjin sample app, most of which are also implemented in BankSimplistic.\n\n**[Domain-Driven Design by Eric Evans](http://books.google.com/books?id=7dlaMs0SECsC)**\n\nFor basic concepts like _aggregates_, _aggregate roots_, _entities_, etc. you can find several resources around the web, although the canonical one is the original DDD book by Eric Evans. This is gold.\n\n**[CQRS clarified](http://www.udidahan.com/2009/12/09/clarified-cqrs/)**\n\nUdi Dahan is one of the main promoters of the CQRS pattern. This post is a nice introduction to it.\n\n**[Why use event sourcing](http://codebetter.com/blogs/gregyoung/archive/2010/02/20/why-use-event-sourcing.aspx)**\n\nGreg Young is another well known supporter of CQRS, particularly if combined with Event Sourcing. In this post he explains his particular vision of Event Sourcing and the motivations and benefits of using it with CQRS.\n\n**[Event Sourcing](http://martinfowler.com/eaaDev/EventSourcing.html)**\n\nFowler's offers here a more comprehensive description of Event Sourcing, including not only its benefits but also some drawbacks.\n\n## Let's explore together ##\n\nIf you're interested in exploring further the ideas and patterns behind BankSimplistic feel free to contact me, open issues in the tracker, add comments to the code or fork the project and share your own experiments (there are a lot of things to try by just looking at the original Fohjin). \n\n-- Luismi Cavallé\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcavalle%2Fbanksimplistic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcavalle%2Fbanksimplistic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcavalle%2Fbanksimplistic/lists"}