Elixir Overview and Tutorial (as told in a Wizard fable)

Interested in Learning the Elixir language? Join us in this entertaining Elixir tutorial and overview.

This post will spin a yarn about an ambitious wizard, Alatar, and his quest to revamp a magic web storefront using Elxir. We will observe Alatar decide on Elixir as his development platform, and follow him on the journey of learning and implementation. Along the way, he will utilize several frameworks written for Elixir (including Phoenix, Ecto, and Poison).

We will also see Alatar embrace the future, by hosting the whole thing within Docker containers. Finally, we will share Alatar's triumph as he finishes a proof of concept REST API, complete with a monitoring solution using Scout. There's enough here for mere mortals to follow along and create their own proof of concept, and hopefully will lead to them becoming master crafters of Elixir in their own right!

image_0.jpg

Trouble Brewing

Alatar Ulrazohr was a 19th generation wizard, from a long line of legendary wizards. His family had been in the Magic retail business ("Ulrazohr Magic") for most of those generations. They sold everything a sorcerer might need, including wands, potions and even the occasional magical beast. Business was strong, Alatar's magic continued to improve, and young Ezaxar sitting on his knee represented the 20th generation of Ulrazohr wizards. All seemed good - what could a sorcerer in Alatar's position possibly have to worry about?

image_1.jpg

As it turns out, quite a bit! While the business appeared healthy, the competition continued to encroach. Otorish's Wonders down the lane was winning over customers lately with their loyalty program. Elzanaxx's Oasis featured inventory from the Darklands, something Ulrazohr was lacking.

And rumor had it (gasp!) that Amazon was trialing a magic department. How could Ulrazohr Magic upgrade their system, and compete in this scary new world? It was enough to make a enchanter of wind and sea lay awake at night, wondering about the future.

Alatar's mother, Atarish, had gained quite a bit of fame a few decades back for putting a web front end on their little business. Overnight, magicians from over the hills and far away could shop at Ulrazohr's.

Business boomed, and legends grew. However, their website was starting to show its age, and limped along on antiquated technology. It struggled under load (don't even mention the weekend of the Mage games of '17, when the whole thing crashed!). Even under the best of times, Alatar had no real way of knowing how things were running. A wizard is not used to flying blind, and Alatar's increasingly gray beard was a testimony to the stress. Alatar felt a great quest for knowledge was to come in the near future.

Alatar's Quest

So there he sat at his keyboard, Googling "REST API", looking for some way out of this bind. After reading through numerous posts, blogs, tutorials, and how-tos, he was at a loss. None of this these things looked easy. Pythons were meant for tasty magical stew, not computers! A Ruby was something to covet and treasure, not type! Just about to give up and throw in the towel, Alatar's eyes drifted across something that caught his attention...

"Elixir!", he thought to himself. "This sounds like a technology that a humble manipulator of time and space can get behind!".

And so it began...Alatar rolled up the sleeves of his hefty magical wizard robe, and began his journey.

Become the Student

Speak the Language

First things first, Alatar needed to learn the language. As with any self-respecting modern computing framework, Elixir has top-of-the-line documentation. It is based on the Erlang VM), another respected and battle-hardened framework. Well known for being highly available, fault-tolerant, and distributed, this sounded like the perfect language to power a web service. Alatar was feeling hopeful. After walking through some tutorials in their documentation. Alatar was ready to put it to work.

Wrapping it in REST

Next question - would it work as the engine for a REST API? There are many responsibilities and concerns to manage when running a REST API, and Alatar didn't want to re-invent the wheel. Poking around a little further, he discovered Phoenix, a framework that did just that. "Battle-Proven Technology" read the byline on their website. This appealed to Alatar - while generally a peace-loving, smoke-ring-blowing wizard, he was raised on stories of ancient battles with evil creatures. "Battle Hardened", eh? Sitting further upright in his seat, Alatar started to warm to this task!

Storing Data

How about the database? Phoenix had that covered as well, using the Ecto toolkit to provide easy data access. Ecto's documentation showed examples of using PostgreSQL and MySql databases. Good! Phoenix, Elixir, and PostgreSQL would give Alatar all he needed to conjure a powerful REST API platform!

Docker For All the Things

His enthusiasm waned slightly as he read further into the documentation. Most of the pieces here seemed to be written for linux first, with Windows support added later. Sighing, Alatar glanced at his Windows machine, memories of trying to get "linux-y" things working in the past rising to the surface. This might be beyond the abilities of even Alatar, an elemental summoning wizard! But wait! Here's a pageoutlining how to set all this up in Docker! With Docker, all becomes possible, whether running Windows, OR Linux!

Challenge accepted!

Legendary Implementation

Docker

With a cup of wonderberry tea freshly brewed, Alatar sat down at his machine. First order of business, get things built using Docker. This consisted of the following steps:

  1. Cloning the GitHub repo

  2. Initialize a new Phoenix application. While the repo provides a bash script to simplify, this doesn't work on Alatar's Windows machine. Instead, he used:docker-compose run --rm app mix phx.new . --app MagicShoppe

  3. After mysteriously running for several minutes, things completed and the machine waited for Alatar's next command. Following the instructions in the repo, Alatar updated the /src/config/dev.exs file to point to the Docker PostgreSQL image.

  4. With the config updated, time to initialized the database:docker-compose run --rm app mix ecto.migrate

  5. Finally, start the app:docker-compose up

With the Docker containers humming, and all the setup complete, here's what Alatar sees on his screen:

phoenix_screen.png

By Zurhan's beard, it's a start! Not too exciting...but the seeds have been planted! Where to go next?

zurhan.jpg

Proof of Concept GET

Any wizard worth their salt knows Ulrazohr Magic is known for their top-quality magic wands, so Alatar decided to build the "wand inventory management" system first. With that basic building block, Alatar could learn the framework, and get a picture of the overall REST requirements.

With some quick Googling for "phoenix rest tutorial", he found the following helpful walkthrough. After a quick perusal, Alatar cracked his ancient knuckles, and began coding.

Creating the "wands" resource consists of the following steps:

  1. Adding the "/wands" endpoint to the "/api" scope:

scope "/api", MagicshoppeWeb do pipe_through :api get "/wands", WandController, :index end

  1. Create the "wands" controller:

/lib/magicshoppeweb/controllers/wandcontroller.ex defmodule MagicshoppeWeb.WandController do use MagicshoppeWeb, :controller def index(conn, _params) do # for now, just return empty collection wands = [] json conn, wands end end

With these two simple steps, Alatar was able to use Postman, and invoke the "GET /api/wands" API!

postman.png

While not actually hitting the database, the REST routing had been proven. Now time to make it more real! In order to do that, Alatar needs a "wand" model, and a representation in the underlying database:

  1. Add /models/wand.ex model file:

defmodule Magicshoppe.Wand do # include the Ecto magic use Ecto.Schema # necessary to ensure Poison (Elixir's JSON library) only serializes what we want it to @derive {Poison.Encoder, only: [:name, :length, :power, :insertedat, :updatedat]} schema "wands" do field :name, :string field :length, :float field :power, :float timestamps() end end

  1. Create a migration script:

docker-compose run --rm app mix ecto.gen.migration create_user

  1. Populate the script with the "wand" schema:

defmodule Magicshoppe.Repo.Migrations.CreateWand do # include the Ecto magic use Ecto.Migration def change do create table(:wands) do add :name, :string add :length, :float add :power, :float timestamps end create unique_index(:wands, [:name]) end end

  1. Execute the migration:

docker-compose run --rm app mix ecto.migrate

  1. Manually populate some top-selling wands using Iex, Elixir's interactive shell:

docker-compose run --rm app iex -S mix iex(1)> alias Magicshoppe.Repo iex(2)> alias Magicshoppe.Wand iex(3)> Repo.insert(%Wand{name: "Lightning", length: 10.2, power: 15.3 }) iex(4)> Repo.insert(%Wand{name: "Thunder", length: 11.4, power: 12.8 }) iex(5)> Repo.insert(%Wand{name: "Wimpy", length: 10.2, power: 3.2 })

With all this in place, the GET /api/wands endpoint now returns real data!

real_data.png

Seeing this work end-to-end invigorated Alatar, as if he'd just chugged a Potion of Magic Restoration! With this wondrous framework, Alatar will have a full REST API up and running in no time! Full inventory, ordering, customer management - you name it!

undefined

But as this magnificent architecture took form in Alatar's mind, a troubling thought also raised a question. How in Mordenkainen's name would he monitor this in production, and detect when problems arose? Elixir was completely new to Alatar. What sort of monitoring frameworks did the Elixir/Phoenix archecture feature?

Scout

After some quick Googling, Alatar found the answer to his question - Scout! Scout is a well-established application monitoring system with built-in support for the Elixir/Phoenix application stack. Taking a brief glance at their tutorial, Alatar felt a wave of delight wash over him - this was going to be the easiest part of the project!

Here's how he tackled it:

  1. Added dependency to the project via the mix.exs file (equivalent to package.json in NodeJS, or the gemfile in Ruby)

  2. Download the config file auto-generated by the Scout app. Slick!

  3. Inject small bits (just a few lines of code) into controllers and/or config files

  4. Restart app.

With this accomplished, Scout dutifully reported the registration:

get_started_with_scout.png

After that, Alatar's REST API suddenly began reporting performance, load, and problems to the beautifully rendered Scout website!

undefined

In addition to the immediate satisfaction of seeing REST API calls monitored and displayed in Scout, Alatar was eagerly looking forward to some of their other features, including:

What a day! Alatar leaned back in his chair and contemplated the wonderful journey he'd just undertaken. Several new frameworks, a functioning REST API, and a way to watch it all work. Alatar knew of other stories of magical creatures embarking upon epic quests (something about a Ring?), but surely none was quite so rewarding as the one he'd just undertaken. Sometimes it felt good to be a wizard.

In Conclusion

With the REST API covering the required functionality, and a whole ecosystem to build upon, Ulrazohr Magic's future never looked brighter. Alatar knew their tech future was secure, and diligently monitored! With Elixir's track record of extreme performance, and Scout there to inform when things WEREN'T going as planned, no amount of delirious wand-shopping could stop them now. Alatar smiled once more, cracked his knuckles yet again, and began coding.

We hope you enjoyed this magical Elxir journey. To learn more about Scout and how it can help your application performance monitoring needs, start your trial today.