Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Context-Driven Development: Architecture your code with Phoenix context

Jenny Shih
October 12, 2021

Context-Driven Development: Architecture your code with Phoenix context

Presented at 2021 ElixirConf by Jenny Shih

Note: There are quite a few gifs in the slides. They can be only uploaded as still images so some effects are gone, but that doesn't affect the values this presentation wants to convey.

Jenny Shih

October 12, 2021
Tweet

More Decks by Jenny Shih

Other Decks in Technology

Transcript

  1. Outline • The cunning challenges of contexts • The quest,

    and what did not work • Build-your-own architecture • Revisit contexts • Context-driven development
  2. Outline • The cunning challenges of contexts • The quest,

    and what did not work • Build-your-own architecture • Revisit contexts • Context-driven development
  3. Phoenix MVC structure lib ├── your_app ├── your_app_web ├── controllers

    ├── endpoint.ex ├── router.ex ├── templates └── views Model Controller View /your_app_web /your_app
  4. Phoenix MVC structure lib ├── your_app ├── ??? ├── ???

    └── ??? ├── your_app_web Model Controller View /your_app_web /your_app
  5. Phoenix MVC structure lib ├── your_app ├── ??? ├── ???

    └── ??? ├── your_app_web Model Controller View /your_app_web /your_app Context
  6. concept of context Ecto business logic juggler by Orin zuu

    from the Noun Project The cunning challenges of contexts
  7. The cunning challenges of contexts • Different layers of concerns

    are mixed together. • Relationships between components are ambiguous.
  8. from Phoenix of fi cial guide “Sometimes it may be

    tricky to determine if two resources belong to the same context or not. In those cases, prefer distinct contexts per resource and refactor later if necessary. “ The cunning challenges of contexts
  9. Outline • The cunning challenges of contexts • The quest,

    and what did not work • Build-your-own architecture • Revisit contexts • Context-driven development
  10. from Phoenix of fi cial guide “Contexts are dedicated modules

    that expose and group related functionality.“
  11. Outline • The cunning challenges of contexts • The quest,

    and what did not work • Build-your-own architecture • Revisit contexts • Context-driven development
  12. Clean architecture file structure lib ├── domain ├── use_case ├──

    adapter └── infrastructure ├── model ├── store (interface) └── service
  13. Clean architecture file structure lib ├── domain ├── use_case ├──

    adapter └── infrastructure ├── upload_image.ex └── register_user.ex
  14. Clean architecture file structure lib ├── domain ├── use_case ├──

    adapter └── infrastructure ├── cli.ex ├── web └── store
  15. Clean architecture file structure lib ├── domain ├── use_case ├──

    adapter └── infrastructure ├── cli.ex ├── web └── store
  16. Clean architecture file structure lib ├── domain ├── use_case ├──

    adapter └── infrastructure ├── cli.ex ├── web └── store
  17. Clean architecture file structure lib ├── domain ├── use_case ├──

    adapter └── infrastructure ├── application.ex ├── mailer.ex ├── repo.ex ├── web ├── endpoint.ex ├── gettext.ex ├── router.ex └── telemetry.ex
  18. (Revisit) The cunning challenges of contexts • Different layers of

    concerns are mixed together. • Relationships between components are ambiguous.
  19. • Different layers of concerns are mixed together. Separation of

    concerns 👍 • Relationships between components are ambiguous.
  20. • Different layers of concerns are mixed together. Separation of

    concerns 👍 • Relationships between components are ambiguous. Clear relationship between components 👍
  21. • Different layers of concerns are mixed together. Separation of

    concerns 👍 • Relationships between components are ambiguous. Clear relationship between components 👍 • Very testable 👍
  22. The almighty clean architecture • Separation of concerns • Clear

    relationship between components • Very testable
  23. Outline • The cunning challenges of contexts • The quest,

    and what did not work • Build-your-own architecture • Revisit contexts • Context-driven development
  24. from Phoenix of fi cial guide “Contexts are dedicated modules

    that expose and group related functionality.“
  25. Adapter Infrastructure Domain Use case • model/noti fi cation.ex •

    store/noti fi cation_store.ex • store/user_store.ex Example: User noti fi cation
  26. Use case Adapter Infrastructure Domain • store/user_store.ex • store/noti fi

    cation_store.ex • web/controller/ noti fi cation_controller.ex Example: User noti fi cation
  27. Improve current architecture with context • domain/model/noti fi cation.ex •

    domain/store/noti fi cation_store.ex • domain/store/user_store.ex • use_case/notify_user.ex • adapter/store/noti fi cation_store.ex • adapter/store/user_store.ex • adapter/web/controller/noti fi cation_controller.ex
  28. • domain/model/noti fi cation.ex • domain/store/noti fi cation_store.ex • domain/store/user_store.ex

    • use_case/notify_user.ex • adapter/store/noti fi cation_store.ex • adapter/store/user_store.ex • adapter/web/controller/noti fi cation_controller.ex Improve current architecture with context
  29. • domain/model/noti fi cation.ex • domain/model/user.ex • domain/store/noti fi cation_store.ex

    • domain/store/user_store.ex • use_case/notify_user.ex • adapter/store/noti fi cation_store.ex • adapter/store/user_store.ex • adapter/web/controller/noti fi cation_controller.ex Improve current architecture with context
  30. • domain/model/noti fi cation.ex • domain/model/user.ex • domain/store/noti fi cation_store.ex

    • domain/store/user_store.ex • use_case/notify_user.ex • adapter/store/noti fi cation_store.ex • adapter/store/user_store.ex • adapter/web/controller/noti fi cation_controller.ex Improve current architecture with context
  31. Apply contexts Use case Domain Context Noti fi cation Noti

    fi cation.notify_user Noti fi cation.Noti fi cation Noti fi cation.UserStore Noti fi cation.Noti fi cationStore
  32. Apply contexts Use case Domain Context Noti fi cation Noti

    fi cation.notify_user Noti fi cation.Noti fi cation Noti fi cation.UserStore Noti fi cation.Noti fi cationStore
  33. Apply contexts Use case Domain Context Noti fi cation Noti

    fi cation.notify_user Noti fi cation.Noti fi cation Noti fi cation.UserStore Noti fi cation.Noti fi cationStore
  34. Apply contexts Use case Domain Context Noti fi cation Noti

    fi cation.notify_user Noti fi cation.Noti fi cation Noti fi cation.UserStore Noti fi cation.Noti fi cationStore
  35. File structure ├── noti fi cation │ ├── noti fi

    cation.ex │ ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex
  36. File structure ├── noti fi cation │ ├── noti fi

    cation.ex │ ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex # context
  37. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex File structure
  38. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex File structure
  39. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex File structure
  40. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex File structure
  41. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex File structure
  42. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex File structure
  43. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex File structure
  44. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex File structure
  45. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex File structure
  46. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex File structure
  47. ├── noti fi cation │ ├── noti fi cation.ex │

    ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex The external layer
  48. elixir_lab ├── noti fi cation │ ├── noti fi cation.ex

    │ ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex The external layer
  49. elixir_lab ├── noti fi cation │ ├── noti fi cation.ex

    │ ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex elixir_lab_external ├── noti fi cation_store.ex ├── repo │ ├── schema │ └── user_repo.ex ├── web (Phoenix) The external layer
  50. elixir_lab ├── noti fi cation │ ├── noti fi cation.ex

    │ ├── noti fi cation_store.ex │ └── user_store.ex └── noti fi cation.ex elixir_lab_external ├── noti fi cation_store.ex ├── repo │ ├── schema │ └── user_repo.ex ├── web (Phoenix) The external layer
  51. • Separation of concerns • Clear relationship between components •

    Very testable • Groups related functionality together 👍 Result of applying context
  52. Outline • The cunning challenges of contexts • The quest,

    and what did not work • Build-your-own architecture • Revisit contexts • Context-driven development 🏁
  53. Context-driven development • Separate your business concerns. • Take advantage

    of Elixir’s fl exibility. • But use it carefully.
  54. Context-driven development • Separate your business concerns. • Take advantage

    of Elixir’s fl exibility. • But use it carefully. • Make your architecture scream.
  55. Resources Books • Clean Architecture: A Craftsman's Guide to Software

    Structure by Robert C. Martin • Functional Web Development with Elixir, OTP, and Phoenix by by Lance Halvorsen • Domain Modeling Made Functional by Scott Wlaschin • Implementing Domain-Driven Design by Vaughn Vernon • Programming Phoenix by Bruce Tate, Chris McCord and José Valim
  56. Resources Videos • Building Beautiful Systems with Phoenix Contexts and

    DDD by Andrew Hao • Lonestar ElixirConf 2017- KEYNOTE: Phoenix 1.3 by Chris McCord • Ruby Midwest 2011 - Keynote: Architecture the Lost Years by Robert Martin
  57. Resources Articles / Blog posts / Forum questions • https://hexdocs.pm/phoenix/contexts.html

    • https://elixirforum.com/t/hexagonal-architecture-in-elixir/32225/16 • https://elixirforum.com/t/how-to-determine-contexts-with-phoenix-1-3/4367 • https://aaronrenner.io/2019/09/18/application-layering-a-pattern-for-extensible- elixir-application-design.html • https://www.destroyallsoftware.com/screencasts/catalog/functional-core- imperative-shell • https://blog.cleancoder.com