Building REST Server with Elixir

Alex Pliutau - Oct 7 '17 - - Dev Community

I always wanted to try Elixir because of it's nice Erlang ecosystem and because it's similar to Go in a lot of points. I was thinking what I can start with, and I decided to build, yes... a REST server. It took me around 1 hour to install Elixir, and build a simple REST server using maru RESTful framework.

I built a small items API using JSON and Agent as storage. Let me go through all actions to build.

Prerequisites

You should only install Elixir, if you're using brew: brew install elixir.

Create new Mix project

Mix is installed together with Elixir, so you just need to run one command to create a project, Mix will create all initial files for you: config, deps, lib, tests, README.

mix new elixirrest
Enter fullscreen mode Exit fullscreen mode

Define dependencies

As we decided to use maru package, we have to add it to mix.exs file.

def application do
    [applications: [:logger, :maru], mod: {Elixirrest, []}]
end

defp deps do
    [{:maru, "~> 0.2.8"}]
end
Enter fullscreen mode Exit fullscreen mode

To get and compile dependencies you have to run this command in elixirrest folder:

mix do deps.get, compile
Enter fullscreen mode Exit fullscreen mode

Configuration

Mix created a file config/config.exs, where we can put all configuration we need, for different environments you can create a separate file, but in our example let's have only one with port 3030:

use Mix.Config

config :maru, Elixirrest.Api,
    http: [port: 3030]
Enter fullscreen mode Exit fullscreen mode

API

I created a folder lib/elixirrest with 2 files: api.ex, agent.ex. In the first we will define our API, and second will be used for as storage worker.

API contains only 2 endpoints: GET to list all items and POST to create new item, they use Agent as storage.

defmodule Elixirrest.Api do
    use Maru.Router
    alias Elixirrest.Agent, as: Store

    namespace :items do
        desc "get all items"
        get do
            Store.get |> json
        end

        desc "creates an item"
        params do
            requires :name, type: String
        end
        post do
            Store.insert(params) |> json
        end
    end
end
Enter fullscreen mode Exit fullscreen mode

Supervisor

To start Agent we just add it to supervision tree in lib/elixirrest.ex:

defmodule Elixirrest do
    use Maru.Router

    def start(_type, _args) do
        import Supervisor.Spec, warn: false

        children = [
            worker(Elixirrest.Agent, [])
        ]

        opts = [strategy: :one_for_one, name: Elixirrest.Supervisor]
        Supervisor.start_link(children, opts)
    end
end
Enter fullscreen mode Exit fullscreen mode

Run and Test

Run this command in elixirrest folder:

iex -S mix
Enter fullscreen mode Exit fullscreen mode

If you don't see any errors you can test API endpoints:

curl -XPOST -d "name=test" http://localhost:3030/items
curl http://localhost:3030/items
Enter fullscreen mode Exit fullscreen mode

I pushed project into this repository in case you want to check or contribute.

Original post in my Blog

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .