I wanna start this article stating that I'm a real noob in Phoenix and Elixir in general, so keep that in mind. Be gracious if I say anything obviously wrong and please comment about it!
Now, before going any further, let us all agree that code organization is hard! We had a lot of advances in that area with the advent of MVC for web apps, thanks to frameworks like Ruby on Rails, but they couldn't solve all our problems. As our apps grew bigger, it became clear that MVC alone couldn't cut it.
We started to look at other forms of code organization. First, we had the skinny controllers, fat models movement. Then we also started to look more carefully at things like Domain-Driven Design and the Repository Pattern. Some frameworks today have some opinions on how we should organize our code that goes beyond MVC.
Phoenix is one of them introducing contexts. Now that I have built some small apps with Phoenix I think that contexts are pretty easy to understand but not everyone feels the same.
And I understand! The way they are introduced at the docs makes you think that maybe you need to think harder about your problem and how you want to organize the code before-hand. Proper design is hard! That can be a downer if all you want is to prototype and try ideas fast.
But the way I see contexts now is that they are just another layer in your app. If you pay attention to the way Phoenix structures code with generators, you will see that we don't have a model anymore. We have a schema and it is easy to think that the schema is the model. But I don't think that is the case. A schema is a very thin layer that should produce changesets. Any other business-related functions can live outside of it.
That is where contexts shine. They are not only a parallel to a model on a classical MVC app, but they also help you organize your code around similar concerns. Much like you would do when working around a specific domain. But if all you want is just prototype, you can have a schema + context combo for everything and that is okay!
The good thing about Phoenix/Elixir is that refactoring should be easy (because functional programming 🕶️) and if you go with the wrong design at first, maybe you can try something different without going insane.
What do you think about contexts? Let me know!