Hello everyone,
I’m currently reading the book “Domain Driven Design: Tackling Complexity in the heart of software” by Eric Evans and developing a toy project to begin to understand what’s all about (and implement hexagonal architecture too).
Somewhere in the book, Eric stated that domain expert should be able to read and understand the code. In my understanding this means that domain-related code should be as less tech related as possible. But how far should I go this path.
For example, I’ve got to register a user with a first name and last name. I decided to chose Ecto for everything related to validation, then I’va got a User
module which is like this
defmodule Account.User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field(:uuid, Ecto.UUID)
field(:first_name, :string)
field(:last_name, :string)
end
def changeset(user, attrs) do
user
|> cast(attrs, [:first_name, :last_name])
|> validate_required([:first_name, :last_name])
end
def register_changeset(user, attrs) do
changeset(user, attrs)
|> put_change(:uuid, Ecto.UUID.generate())
end
end
This should be OK as it is some kind of “deep implementation”, but for the API, which should be understandable by domain expert, what is the best?
My first (naive and classic) approach was this one:
defmodule Account do
alias Account.User
import Ecto.Changeset
def register_user(data) do
%User{}
|> User.register_changeset(data)
|> apply_changes()
|> DataLayer.insert()
end
end
which I think is too tech-related. Therefore, I tried to be more user-friendly and explicite and end up with something like this:
defmodule Account do
alias Account.User
def register_user(data) do
data
|> User.validate_register()
|> User.generate_uuid()
|> User.save()
end
end
which is easily understandable and expose all steps of the data processing but raise the following question:
- Does this mean that I need to have a domain-expert-friendly layer and a more technical layer (which will effectively does the work)?
And additionally, i wonder if Phoenix contexts are just the right balance between too much coupling and too “non-tech” code.
What do you think? Can you help me clear my mind?
I understand that this matter is important but I can’t yet express it in code…
Thant you