Using Elixir Phoenix in a Commercial SaaS Project
Linkly is written in Elixir.
I had always wanted exposure to the Erlang ecosystem, and Elixir is an easy route.
I won’t cover the benefits of BEAM or Erlang directly here, as that’s been written about elsewhere. Instead, I’ll focus on the practicalities of using Elixir Phoenix for a real project.
I’m going to assume you know what Ruby on Rails is, as Phoenix, Elixir’s web framework, is heavily inspired by Rails.
Actually Programming in Elixir Phoenix
Writing in Elixir is a joyful experience.
It follows similar paradigms to Rails, including MVC, and even looks similar.
Unlike Rails, the code is compiled before it is run. This is a useful step as it allows you to catch errors that you otherwise might not have.
Models in Phoenix are grouped into ‘Contexts’. This is an extra level of abstraction, intended to create clear separation between parts of applications, e.g. Users and Products. Each context can contain any number of models.
Performance
A lot has been made of performance on other blogs, so I’ll cover the practical side here.
For a fully featured web framework, the performance is clearly a lot faster than Rails, and requires substantially less hardware to run.
The time ‘to boot’ of running mix phx.server vs rails server is faster. Even when developing on a laptop, pages load noticeably faster with Phoenix.
Availability of Packages for Elixir Phoenix vs Rails
Superficially, it seems like there’s a difference here. Rails has many thousands of gems versus Elixir’s Hex repository.
As it happens, almost everything you’d actually use is available in the Elixir Hex package system - JSON parsers, HTTP clients, tools for formatting and parsing Markdown - it’s all there, and the module quality is outstanding.
In Rails, there are substantially more gems,, but you would never include them in a real project, due to their unmaintained status or risk associated with building too many external dependencies into your application.
Platforms like Stripe and Recurly maintain their own Rails gems for interacting with their APIs. This can be handy, and are generally lacking support for Elixir.
I found, however, it was very easy to use Elixir’s Tesla package for interacting with HTTP endpoints of services, and finally ended up preferring working this way, versus using pre-packaged gems, as it’s lighter, and allows you to understand what’s happening.
Database Abstraction - Ecto and ActiveRecord
Ecto is not as fully featured as ActiveRecord.
It’s not intended to be.
Ecto is a simple database wrapper that maps database queries to Elixir objects.
Initially, I found it to be frustrating that it didn’t work just like ActiveRecord.
However, Ecto lets you interact with the database in a very straightforward way, and actually makes programming web applications much easier.
With ActiveRecord, once you start building complex queries, it takes longer to figure out ActiveRecord than just writing a query as SQL.
Having used both, it is my conclusion that using a lightweight database wrapper like Ecto is easier than using a heavyweight abstraction like ActiveRecord.
It gives you the safety of using a database wrapper, without the headache and weight of a 'too clever” abstraction.
Both contain migration and rollback functionality.
The default database for Phoenix projects is Postgres.
For those using NoSQL databases, Ecto works with Mongo.
Better yet, Ecto works with Postgres’ NoSQL features, allowing you to save and query JSON without needing Mongo.
User Authentication
This is somewhere Elixir Phoenix is lacking.
Rails has the Devise module. Phoenix has Coherence, however it is presently unmaintained.
If you want to use a basic username & password login, you will have to build every step of that. That includes hashing passwords, password reset logic, ‘remember-me’ settings etc.
This is tedious and carries substantial security risk.
I opted to use Auth0, which worked with Phoenix just fine. Perhaps this is a better solution anyway, but it would have been nice to have had a choice.
Deployment & Hosting
The main host of Phoenix apps is Gigalixir, a small American company run by Elixir enthusiasts.
Gigalixir is hosted on Google Cloud, so the underlying infrastructure is sound.
Gigalixir’s buildpack makes deployment easy, and supports all of Elixir’s clever deployment strategies (distillery, mix).
It is more expensive than ‘roll-your-own’, but most of the cost is wrapped up in Postgres database hosting.
Elixir Phoenix is so light that it can be run on small docker pods and still handle a very healthy number of requests.
Despite the markup, it is absolutely worth it to take the headache away.
I’ll just add, their customer support is outstanding.
Availability of Programmers
There are substantially fewer Elixir programmers out there.
Elixir is “programmer’s language” -a language people come to, having learnt something else.
Having said that, those who do Elixir are typically better programmers. Perhaps it’s the conscious choice of picking a better language.
It reminds me of the early days of Rails, where it seemed like only “rockstars” would use it (versus PHP).
Any good Rails programmer will have no problem picking up Elixir Phoenix, and will be up and running within a few days.
Would I Use Elixir Phoenix again?
Definitely.
I’ve worked with a lot of languages, and Elixir is the easiest and most powerful I’ve worked with.
I look forward to writing Elixir.