Understanding the flow of Phoenix connections

When the request comes in, the router takes a look at the incoming connection (referred to in the future as the conn) and determines where this request needs to get routed to. It could be something that needs to be handled in a way appropriate to the browser, a way appropriate for an API to handle, or it could also just plain and simply be a 404 error that needs to get served out (depending on what the router says exists for that particular web application).

From there, the connection is passed along through the router and into a pipeline of plugs. Plugs are constructs that can be reduced down to functions that take in the connection structure and optionally some options, and then apply some form of transformation (if appropriate) and return out a modified connection structure. The beauty of this idea is in its simplicity; each plug our connection passes through is just a function at the end of the day, and all it is doing is making modifications to the connection if appropriate, or just returning out the connection it was passed in originally. Plugs are a concept that sometimes seems extremely complicated when you're first learning Phoenix, but if you can reduce them down to their core concept (and as a result, see what they really are without any abstractions), it becomes very simple to reason about what they are, when to use them, and how to build new ones to make your own development life simpler. We can think about the flow of data with the following diagram:

Now that we have our connection, and that connection has passed through our plug pipeline, the connection will flow into our controller (as shown preceding). The controller's job is to take in the connection, put together any data that is required from any source and any transformations that need to apply before we can serialize the data, and then determine which view and template everything should be flowing into. A lot of the calls to our Contexts and miscellaneous code/libraries will be happening here or get called from here!

Next, the data flows into our view, which is responsible for serializing the data in such a way that either the templates or an API context can use it. This could be turning the sets of data into JSON for an API or it could be creating variables accessible to the templates.

Finally, if we're working with something closer to a browser workflow, the data will flow into our templates, where we will be able to access the variables to display through our .eex templates (more on this later)! This is kind of the end result of our request workflow, and the results of this final piece of work are what gets sent back to the browser. We'll be doing a good bit of work here since our application will largely be a browser-based application and not an API.

Okay, so now we understand the flow of a request that is going to come into Phoenix, and we can start to reason about how we’re going to start building things!