How to Keep Context Structure Clean and Manageable in a Phoenix Project?

I’ve been exploring Phoenix.Context recently and noticed that many projects seem to structure it differently.
Let’s say we have a context called Catalog, which includes two sub-schemas: Product and Category.

Following the typical approach:

  • catalog.ex should contain the CRUD operations and business logic for both Product and Category.
  • catalog/product.ex should contain the schema definition and changeset logic for Product.

However, when the CRUD logic becomes extensive, catalog.ex grows too long, and you might need to split it up. At that point, it feels like the community has all sorts of ways to handle it—there’s no real standard…

My current idea is to structure it like this:

  • catalog/products.ex
  • catalog/products/product.ex
  • catalog/categories.ex
  • catalog/categories/category.ex
  • catalog.ex

But the module names feel quite long… it’s like having contexts within contexts.
How do you all usually handle this?

Why not just:

  • catalog/product.ex
  • catalog/category.ex
  • catalog.ex

If you ever see catalog getting really big with a lot of product/category stuff maybe then think about extracting that, but this probably goes a long way.

1 Like

“Too long” in what sense? Understanding that will help understand what solutions can help.

FWIW, I find that lengthy Elixir modules are much less of a concern than lengthy classes in OOP languages - mainly because there’s no “shared state”, so modifying one function is much less likely to cause unexpected changes to the behavior of other functions.

2 Likes

I make “subcontexts” and defdelegate in the root if I feel they have gotten too big.

4 Likes