Overview

Elixir, Phoenix and CouchDB — An Introduction

1 Comment

The Elixir MVC Framework Phoenix

Marcel WolfMarkus Krogemann

Abstract

This blog post will show how a functional web application can be built with Elixir and Phoenix in a few, simple steps, without requiring a deeper understanding of functional programming or the Erlang/OTP system.
A small demo application will then help us understand how the Phoenix framework works and appreciate the technical merits of the Elixir ecosystem.
Follow–up blog posts will provide deeper insights into the framework and its components, such as Plug or Ecto. Special attention will be paid to connecting the web application with the document database CouchDB.

Phoenix, Elixir, CouchDB

Introduction

Elixir is a dynamic, functional programming language that leverages the Erlang VM (BEAM). It has a modern syntax that borrows from languages such as Ruby and supports advanced meta programming features, facilitating a smooth entry into the world of Erlang and its interesting runtime characteristics.

Erlang is a functional programming language that has been developed to build highly available, “always–on” systems in the telecommunications domain.
It is well known for its resilience, its transparent approach to building distributed systems and a developer friendly handling of concurrency (Actor Model).

The ecosystem around Elixir is still comparatively small, but is being quickly developed by a growing community of enthusiasts.

Phoenix

The web application framework Phoenix is one of the products that this community has spawned. It greatly simplifies the development of high–performance HTML5 apps, API–Backends and websocket applications.

CouchDB

When we first checked out Phoenix, it became apparent that database adaptors exist mainly for relational databases and MongoDB.
In order to stay within the Erlang ecosystem and to leverage the features of a document database, we decided to integrate with CouchDB.
CouchDB is a NoSQL database, developed in Erlang, that stores JSON documents and exposes its functionalities through an HTTP API.

Having found no readily available database connector that fulfilled all of our requirements triggered our decision to develop our own CouchDB connector in Elixir.
The current release of this connector supports basic create, update and read operations, as well as rudimentary view operations.
The code has been published as an open source project on Github.

Starting a Phoenix Project

In order to bootstrap a new Phoenix project, we make use of the Elixir command line tool mix and apply one of the tasks defined by Phoenix, in this case:

mix phoenix.new <app-name>

As we do not want to make use of a relational database, we exclude the default persistence layer Ecto by adding the –no-ecto flag. So, in order to create a project with name ‘foo’, we type:

mix phoenix.new foo --no-ecto

start phoenix project

After creating the files and folders that make up the project structure, the mix tool prompts us to download and install a set of dependencies — later on we will see where these are declared.

download dependencies

Change into the project root:

cd foo

We now have several options to start the application. To allow interaction with the application’s modules at runtime, we start the application within a REPL (Read–Eval–Print Loop), using Elixir’s interactive shell,  iex:

iex -S mix phoenix.server

phoenix server running 1

This brings up the (as yet empty, but fully functional) application, so that we can now reach it through a web browser on port 4000:

We will be greeted with the page shown below.

phoenix server running 2

Live–Reload

Phoenix has a very useful Live–Reload feature. A change that we make in the currently shown page will immediately become visible in the browser, without us having to manually trigger a reload of the page.
Assuming the application is in the state shown above and we change the underlying HTML template in

web/templates/page/index.html.eex

from this

welcome to phoenix

to this,

phoenix hello world

the web browser will immediately show the effect of that change and render the new state as shown below:

server running hello world

In the iex console, we will see the change being logged:

phoenix live reload

Project structure

Let’s now look into some of the newly created folders:

├── config

The config folder contains project configuration files. Some dependencies also expect their configurations to be stored here, an example being credo, a static code analysis tool.

The configuration mechanism also supports different settings per environment by simply storing them in the appropriate config files: dev.exs, test.exs, etc.

These .exs files (Elixir scripts) are compiled in memory each time they are run, which makes them ideal for storing configuration details and scripts that change often during development.

Some other, less frequently changing configuration artifacts live inside the lib folder.

├── lib
│   └── foo

The .ex files in this folder are compiled to .beam files and then loaded into the Erlang Virtual Machine (BEAM), which makes these files useful for storing higher level, less frequently changing configurations, such as endpoint and OTP supervisor/worker config. For performance reasons, such types of configurations should therefore be stored in lib or subfolders thereof.

├── priv

The priv folder is reminiscent of the Erlang/OTP heritage of Elixir. The OTP specification expects this folder to exist. Its name suggests private content, but in a Phoenix project, it actually contains static resources such as (minified, compile–time generated) JavaScript and CSS files. Database seeding scripts are also commonly stored in priv.

└── web

The Phoenix framework implements the well–known Model–view–controller architectural pattern (MVC).
The web folder contains MVC artifacts like controllers, models and views. In contrast to other MVC frameworks, such as Ruby on Rails, Phoenix differentiates between templates and views. The Templates are getting pre–compiled, which helps to reach the high performance that Phoenix has to offer.

Routing information is stored in router.ex. It contains a mapping of request paths to controller functions.

Static content sources (JavaScript, CSS, images) go into the static subfolder of web.

Phoenix is fully compatible with JavaScript and CSS frameworks as they are typically being used in modern web applications. Just drop them into the appropriate subfolders of web/static and use the configuration mechanism provided by brunch to influence their loading sequence (e.g. load jquery.js before bootstrap.js).

An example configuration (brunch-config.js) can be found in the demo project, which we will introduce next.

“Bird watch”

We have thus far looked at an essentially empty, yet functional walking skeleton project, which already showed some of the ways of working with Phoenix.
However, a real–world demo application allows us to address more of Phoenix’s features and characteristics.
Such a demo application has been made available in a Github repository.

Check out the source code:

git clone https://github.com/mkrogemann/bird_watch

cd bird_watch
mix deps.get

Here, we have made use of the mix build tool to resolve and download the project’s dependencies. mix can also facilitate creating, compiling and testing Elixir projects. We will see more of it in future episodes.

We can also use mix to pre–populate the database by calling an application specific seeding script:

mix run priv/repo/seeds.exs

Now we can start the application

mix phoenix.server

and open it in a web browser:

phoenix bird watch running

Conclusion

In a small number of simple steps, we have created a functional web application and shown how easy it is to make changes that are immediately visible, thanks to the perfect implementation of Live–Reloading. This feature is a real productivity boost.

Another nice trait is the excellent performance of Phoenix web applications. Check out these impressive benchmarks to appreciate its throughput and latency figures.

We will continue development of the demo application “Bird watch” in follow–up blog posts and show more of the advanced functionalities and characteristics of Phoenix, Elixir and OTP.

 

Post by mkrogemann

Elixir

Elixir — Where is your state?

More content about Elixir

Kommentare

  • Raimar Falke

    19. January 2016 von Raimar Falke

    You have to install the elixir and couchdb packages for example with “brew install elixir ; brew install couchdb”. Also before starting the server with “mix phoenix.server” an “npm install” is required.

Comment

Your email address will not be published. Required fields are marked *