Greetings! I’m moving my first steps with Phoenix and I’m having some troubles understanding cross-context relations. I’ve read many discussions about it, the official documentation and articles, but I still think I’m missing part of it.
So sorry for the really huge post.
I’ve found various ways to deal with cross-context relations.
A) The most elegant way seems to be (according to my interpretation of How to determine contexts with Phoenix 1.3 ) to keep contexts completely separated. Entities from one context should refer to entities in another context only via public APIs. Relations should be expressed by simple integer fields instead of “belong_to”, or “has_any”.
B) Another approach I found keeps context separated as in A) but uses foreign keys at database level to ensure integrity.
Question 1) Which are the advantages of B over A ? I’d say that once you have linked two databases tables contexts are not independent anymore.
C) A third way can be found in the official context documentations ( https://hexdocs.pm/phoenix/contexts.html ) which uses both a foreign key and a “belongs_to” relation between different contexts.
Context Accounts has two schema: “users” and “credentials”; there is a TWO WAYS IN-CONTEXT relation:
- users -> has_one -> credentials
- credentials -> belongs_to -> users
Context CMS has two schema: “pages” and “authors”; “authors” has a ONE WAY CROSS-CONTEXT relation with Accounts.users:
- CMS.authors belong_to Accounts.User
- BUT “users” misses the reverse “has_one” relation
Question 2) Is it better to avoid TWO WAYS CROSS-CONTEXT relations or is it something one choose case by case? E.g. if we need to follow the relation in both ways or not.
Question 3) Is it true my understanding that option C is a sort of compromise between a monolithic project and full context separation? I say this because it doesn’t really separate contexts due to the “belongs_to” relations but still uses explicit interfaces between contexts.
Now, a slightly more complex example.
Let’s start from the blog project described in the official documentation ( https://hexdocs.pm/phoenix/contexts.html ) and summarized above as point C).
Let’s say we decide to add to this project the possibility for users to upload videos and publish code (not a very realistic example I know…). I’d be tempted to create additional Contexts videos and code:
- Accounts
- CMS
- Video
- Code
Let’s also say that blog posts, videos and software projects can have multiple authors.
Now, I really can’t see how to keep context separated: everything is strictly tied to everything else: users can have many videos, blog posts, software projects.
Let’s add a comment system on the top pf it: regular users (not necessary authors) can comment everything published. This is another feature that span all contexts.
I don’t think we can handle all these many to many relations only with integer fields instead of cross-context “has_many” relations, so here comes my fourth question:
Question 4) Is my choice of contexts poor? Or this example require a monolithic structure and there is nothing we can do to really isolate parts of it?
Thanks to everybody who took the time to read all this!