conduit
conduit copied to clipboard
"Building Conduit" book suggestions
Edits/suggestions for the book, Building Conduit. Have an edit or suggestion? Leave a comment here!
Edits
- [ ] in "Writing our first unit test" aggregates/user_test.exs example
defmodule Conduit.Accounts.UserTestshould beConduit.Accounts.Aggregates.UserTest - [ ] in "Writing our first read model projection" command validation example module names are wrong
Conduit.Validations.Validators.String— the namespacing for validators changes over the course of a couple commits, and the examples in the book do not match - [ ] The Unique validator module name does not match the module name added to the application supervisor
Suggestions
- [ ] i was confused about the phoenix-generated context code and tests until i looked at a commit where you removed all of that — it would have been nice to have that direction and some reassurance that “it’s going to be ok” in the book — it’s a brave new world!
- [ ] the refactoring of the readstore database setup to
Conduit.Storage.reset!for tests is not mentioned in the book, but relied upon in the examples - [ ] the guardian configuration is out of date. guardian 1.0.0 has been released and the setup/usage is a little different now
- [ ] generated phoenix test moved away from fixtures like
fixture(:user)in favor ofuser_fixture(). This dealt with issues users were having once tests expanded beyond the most simple case.
@andreapavoni Ecto changesets aren't used because the write model, which accepts commands, persists its state via domain events appended to an event store. There's a separate read model which later projects these events into the database using Ecto.Multi.
There's an example of enforcing uniqueness in the Conduit sample repo on GitHub. The approach is to build a read model projection containing the unique values which is populated from your domain events. You query this projection as part of command validation to ensure the value has not already been used.
-
Conduit.Blog.Projectors.ArticleInserts each published blog into the
blog_articlestable, which contains theslugfield, by projecting theArticlePublishedevent. -
Conduit.Blog.Validators.UniqueArticleSlugValidates that no article already exists with a given slug by querying:
defp article_exists?(slug) do case Blog.article_by_slug(slug) do nil -> false _ -> true end end -
Conduit.Blog.Commands.PublishArticleIncludes validation on the
slugfield to ensure it is unique:validates :slug, presence: [message: "can't be empty"], format: [with: ~r/^[a-z0-9\-]+$/, allow_nil: true, allow_blank: true, message: "is invalid"], string: true, unique_article_slug: true
Does that make it any clearer for you?
@slashdotdash thanks for the quick reply! I've deleted my comment few minutes after I wrote it because I've seen later in the book some clever workarounds for username/email uniqueness, by using a GenServer to claim/reserve the data.
I'm going to check the part about articles and slugs. Thank you again!
On page 30 (Accounts > Register a user > Constructing commands from external data) adding the ExConstructor package is missing a step (I think): adding it to application in mix.exs.
def application do
[applications: [:exconstructor]]
end
https://hexdocs.pm/exconstructor/ExConstructor.html
Thanks!
Hi guys,
Is there an example of value-object in this tutorial?
I was using the Conduit tutorial as the main guide. However, in that example, it does not mention how to represent value-object and how we can associate them with entities. It seems that they are just using entities for everything.
Could someone support me?
Thanks!
Building Conduit: Accounts - Building our first command
Not sure if this is the best place, but really enjoying the book. I found one issue in "Building Conduit", that's not a big deal but might help someone else. The UserRegistered event module needs to be created and aliased in order for iex to start, as in the examples a few paragraphs earlier.