conduit icon indicating copy to clipboard operation
conduit copied to clipboard

"Building Conduit" book suggestions

Open dustinfarris opened this issue 7 years ago • 5 comments

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.UserTest should be Conduit.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 of user_fixture(). This dealt with issues users were having once tests expanded beyond the most simple case.

dustinfarris avatar Nov 28 '17 15:11 dustinfarris

@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.Article

    Inserts each published blog into the blog_articles table, which contains the slug field, by projecting the ArticlePublished event.

  • Conduit.Blog.Validators.UniqueArticleSlug

    Validates 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.PublishArticle

    Includes validation on the slug field 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 avatar Apr 19 '18 09:04 slashdotdash

@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!

andreapavoni avatar Apr 19 '18 09:04 andreapavoni

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!

toraritte avatar Sep 07 '18 23:09 toraritte

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!

Yamilquery avatar Dec 10 '18 17:12 Yamilquery

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.

mintymac avatar May 20 '19 18:05 mintymac