"Top-level contexts" using Phoenix 1.3

Hi, I’ve been sidetracking Elixir and Phoenix for some time now, and I have finally made the time to start learning a little bit of both…

So, now I’m trying to grasp the concept of contexts in Phoenix 1.3. After reading about the subject, I have to admit that it is is really tough to make those kinds of decisions up front about the app design (basically naming stuff :sweat_smile:).

For the simple cases like the infamous Blog and Account namespaces its super easy and makes sense right away.
But for something like an app that monitor blogs, where I have a Blog as a “top-level context” is not clear anymore (some would say BlogManager, but that doesn’t seem proper).

If I could give one more example, imagine an app, something int the contexts of a game where I have tables for Characters, Actions, Creatures, Items, Skills, Races, Users.
All those tables seem to me like what I’m calling “top-level contexts” as they don’t seem to fit in a proper context by themselves. Others could argue about using a “Game” namespace, but almost everything in this scenario would end up in the same namespace.

So, basically, I’m trying to collect some tips and tricks to make a little bit easier to reason about this. I’m sure most of you using Phoenix right now are going through that. So any advice at all is welcome :smile:.

3 Likes

It is probaby ok to start with a unique context, call it game or core…

Remember that in the end, contexts are usually calling schemas and repo functions.

A game is quite simple, Maybe You can use Accounting, Core and Stats contexts. Accounting would manage player’s accounts. Stats would be managing special statistics requests about game status, like high scores, top ten players etc. And Core all the rest.

You might see more complex situation trying to simulate real companies workflows.

eg a Bank :slight_smile:

There would be back office, portfolios etc.

2 Likes

This sounds good enough to me. I’m trying to absorb as much information about this as I can…
I have been reading a lot of negative critics towards contexts, and my view was also kinda of biased by those critics.
But as you have put:

Remember that in the end, contexts are usually calling schemas and repo functions.

I also have read something Chris posted along the lines of: “Contexts are just well-named modules”.
I think that the concept is finally clicking, thanks :smile:

1 Like

That’s it - that’s all there is to “contexts” in a Phoenix application - modules and functions defining public interface of your application. Anything more, any more philosophy you’re going to attach to this is entirely your choice.

From: Michał Muskała: Putting Contexts in Context

You may also interested in [this recent post by Chris McCord]
(How to chain controller actions or DB inserts in Phoenix?) and possibly this recent topic.

One thing to keep in mind is that the term context is overloaded in the ecosystem - which is probably contributing to some of the confusion. Domain Driven Design has the concept of bounded contexts and Phoenix contexts can be bounded contexts and for complex problem domains Phoenix contexts should strive to be bounded contexts.

But I suspect that the core motivation behind Phoenix contexts is far more elementary:

Now “high cohesion, low coupling” sounds rather hand-wavy but the effects are evident during maintenance. For tightly coupled systems

A change in one module usually forces a ripple effect of changes in other modules.

which low (or loose) coupling generally avoids. Tight coupling usually happens when client code depends too much on a module’s implementation details.

The most common manifestation of low cohesion is that there is too much logic in a single module - it really should be separated into into a set of loosely coupled modules. Low cohesion modules are the proverbial Big Ball of Mud - huge API, difficult to reason about, and that module seems to need changes for every update.

4 Likes