During the last week, I was playing around with some Phoenix toy projects and I must say that, so far, it is an excellent framework for building reliable and highly concurrent web apis.
I mentioned previously that I am working on a mobile application and that We(the team) decided to use the elixir/erlang platform. The mobile application’s backend service is highly concurrent in nature and, again so far, Phoenix seems to be a perfect fit for the kind of problems we are trying to address.
In this post, I would like to highlight the routing/controllers aspect of Phoenix.
The Phoenix framework is based on Plug, I would define Plug as a middleware between web servers and web frameworks.
It essentially allows the developers to create a pipeline in which an http request can be shoved upstream passing through the plugs (processing steps) of the pipeline, then the processed http request can be passed downstream to a controller action.
Pipelines are composed of plugs which can be simple functions or regular modules. As we can see in the previous flow chart, the steps can be to:
- filter out content types which are not
- fetch the current session
- verify that the http request header contains an authorization token
- load the resource encrypted inside the authorization token
These pipelines are defined in the
web/router.ex file and looks something like this:
We can factor common request processing steps into pipelines, which allows us to keep our controller actions concise and on point. In the asp.net core world, the same thing can be achieved by using filters.
In the same
web/router.ex file, we can define path to controller action mappings(aka routes) as follows:
In the previous listing, the
scope macro is used to define a scope composed by a sub-path(
/api) and usually the application’s module (
We can explicitly choose which defined pipeline to use when handling requests routed via a specific scope, this enables essentially pipeline reuse which is very nice.
In addition, it is possible to define
verb, "/path", Controller, :action_method routing rules and to create a RESTful resource with the
resources function given that the controller module provides conventional methods for handling common http verbs, for example the
:show function is associated to the HTTP
GET verb by convention.
Controllers are actual elixir modules and defined under the
web/controllers folder with their action methods and looks like this:
Here we defined a
show action that gets an
id from the http request create a
User and then renders the created user in the response via a
json template (
render function can be used to render html or json templates and there are many more convenience methods that allows to put stuff in the http response, among them:
jsonwhich allows to render a map into a json string
textwhich returns a plain text response, can be useful for fiddeling
put_statuswhich sets the http response status code