OctoDomain
OctoDomain is a Ruby gem that abstracts data models and allows for the easy and safe creation of domain objects when an application becomes sufficiently complex to warrant them.
Benefits:
- Creating domain objects and mapping them to data models is easy.
- Domains are easy to test.
- Clients can be created to attribute load to specific dependencies.
- Extensible with solid defaults. Pass a custom transport to use a different messaging system e.g. JSON.
- Ensures domain arguments are primitives that could be serialized if the domain is extracted.
- Easy to mock interfaces in dependencies which allows for fast and simple tests.
Installation
Install the gem and add to the application's Gemfile by executing:
$ bundle add octodomain
Usage
OctoDomain allows you to expose your data access in the form of domain objects that are accessed by a client.
For example, a user domain may expose methods to find and create users like the following:
class UserDomain < OctoDomain::Base
# Creates a UserDomain::UserValue value object that can be used to map the result of
# domain methods to a value object
value :user do
attribute :id
attribute :email
attribute :display_name
end
# message exposes a domain method that can be called by a client
message :create_user # returns nil, because there is no serializer passed
message :find, serialize_with: :user # maps the returned user model object to the `user` value object defined above automatically
private
# Implements the `create_user` message behavior exposed by the message above
def create_user(name, age, addresses)
User.create({name: name, age: age, addresses: addresses})
nil
end
# Implements the `get_user` message behavior
def find(id)
User.find(id)
end
end
Then to interact with the domain, you would create a client:
# Optionally specify a transport to use. e.g. use LocalTransport for method calls, or implement JSONTransport for JSON over HTTP
user_domain = UserDomain.client_for("auth_domain", transport: OctoDomain::LocalTransport.new)
user_domain.create_person("Fox Mulder", 30, ["123 Main St"])
user = user_domain.get_person(31) # returns a UserDomain::User value object
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests.