Posts in this series
Alright! Let’s get busy! In this article we’ll install Elixir, Phoenix and all the other bits we need for our Banking API project. I’m a Linux user at home, and aware of macOS since I use it at work, but no idea about Windows support since I haven’t used it for development for a long time.
If you already have Elixir and Phoenix installed, skip over this section
Let’s get started. You’ll need:
I tend to avoid Linux distro packaging of programming languages, since they usually evolve faster than distro release cycles - especially true for Debian, notorious for lagging behind quite a bit on its stable channel. So let’s use a “version manager” to install languages locally. I used to be a big fan of RVM and nvm but they’re specific to Ruby and nodeJS, respectively, which is a bore because you need to learn N tools to manage N languages.
Enter asdf, which exposes a stable interface to manage all of its supported languages and supports bash, ZSH and Fish (my shell of choice). If you don’t want to use asdf, feel free to install Erlang (21+) and Elixir (1.8+) by other means. On macOS, homebrew is usually quite quick with updates, and the community is quite active with fixes, but I’d still suggest using asdf.
Installing asdf is quite easy. Clone it locally:
$ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.6.3
Then, if you use bash, do:
$ echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc $ echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
or with fish:
$ echo 'source ~/.asdf/asdf.fish' >> ~/.config/fish/config.fish $ mkdir -p ~/.config/fish/completions; and cp ~/.asdf/completions/asdf.fish ~/.config/fish/completions
and open a new terminal or terminal tab to load it. Check it’s installed with:
$ asdf --version
Next up, we’ll install the Erlang and Elixir plugins:
$ asdf plugin-add erlang https://github.com/asdf-vm/asdf-erlang.git $ asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git
There are a few build requirements for Elixir and Erlang. For Debian:
$ sudo apt install curl build-essential autoconf m4 libncurses5-dev libwxgtk3.0-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libssh-dev unixodbc-dev xsltproc fop
The Erlang plugin’s README has more info on package names for other distros and macOS. Let’s install the most recent 21.x version (this will take a while):
$ asdf install erlang 21.2.6 $ asdf global erlang 21.2.6 # sets this version as default
And the most recent Elixir version (this will be super quick):
$ asdf install elixir 1.8.1-otp-21 $ asdf global elixir 1.8.1-otp-21 # sets this version as default
You’ll also need PostgreSQL for our databases (read model and event store). For this I suggest you do use your distro’s packages, and if you’re on macOS Postgres.app is pretty good. Be sure to use at least version 9.6, ideally 11.
The final piece is the Phoenix web framework, which will handle all the HTTP busywork on our project. I won’t give a full introduction to Phoenix, since our interaction with it will be very small. Installation is pretty simple. We’ll need Hex, the Elixir package manager first:
$ mix local.hex
Then the Phoenix command line tools:
$ mix archive.install hex phx_new 1.4.1
If you want live-reloading of code in development (and you should, it’s amazing),
you’ll need to install
inotify-tools. For Debian:
$ sudo apt install inotify-tools
Check its wiki for info on setting it up for other distros.
And that’s it, we’re all set!
Let’s create our project folder. Elixir ships with Mix, a powerful mix of task runner and dependency fetcher. Having it built-in to the language is a huge boon for productivity. Phoenix’s command line tools are invoked using it.
To create out project in a
$ mix phx.new bank_api --module BankAPI --database postgres --no-webpack --no-html
We set the main module name, PostgreSQL as the database, skip webpack and HTML views.
This is what you should see:
* creating bank_api/config/config.exs * creating bank_api/config/dev.exs * creating bank_api/config/prod.exs * creating bank_api/config/prod.secret.exs * creating bank_api/config/test.exs * creating bank_api/lib/bank_api/application.ex * creating bank_api/lib/bank_api.ex * creating bank_api/lib/bank_api_web/channels/user_socket.ex * creating bank_api/lib/bank_api_web/views/error_helpers.ex * creating bank_api/lib/bank_api_web/views/error_view.ex * creating bank_api/lib/bank_api_web/endpoint.ex * creating bank_api/lib/bank_api_web/router.ex * creating bank_api/lib/bank_api_web.ex * creating bank_api/mix.exs * creating bank_api/README.md * creating bank_api/.formatter.exs * creating bank_api/.gitignore * creating bank_api/test/support/channel_case.ex * creating bank_api/test/support/conn_case.ex * creating bank_api/test/test_helper.exs * creating bank_api/test/bank_api_web/views/error_view_test.exs * creating bank_api/lib/bank_api_web/gettext.ex * creating bank_api/priv/gettext/en/LC_MESSAGES/errors.po * creating bank_api/priv/gettext/errors.pot * creating bank_api/lib/bank_api/repo.ex * creating bank_api/priv/repo/migrations/.formatter.exs * creating bank_api/priv/repo/seeds.exs * creating bank_api/test/support/data_case.ex Fetch and install dependencies? [Yn] # <--- press Y or Enter here! * running mix deps.get We are almost there! The following steps are missing: $ cd bank_api Then configure your database in config/dev.exs and run: $ mix ecto.create Start your Phoenix app with: $ mix phx.server You can also run your app inside IEx (Interactive Elixir) as: $ iex -S mix phx.server
Switching into the new generated folder, let’s create the database:
$ cd bank_api ; mix ecto.create
And start the Phoenix app server:
$ mix phx.server [info] Running BankAPIWeb.Endpoint with cowboy 2.6.1 at http://localhost:4000
Now if you go to
http://localhost:4000 you should see something like this in your
This error is perfectly normal, since we don’t have any routes and we opted for no default HTML views!
Throughout the series, we’ll develop a simple HTTP API for a bank that will allow us to open and close accounts, deposit and withdraw funds and transfer them between accounts. A simplistic example, but we’ll be able to cover Aggregates, Commands, Events, Projections and Projectors, supervised Process Managers, Routers, Commanded middleware for auditing and validation, and of course testing for the API’s functionality.
Stay tuned for the next post!
Cover image credit: PIXNIO