This is an annotated example of a web application written using Elixir and Plug.
Create mix.exs:
```elixir
#
# Mix is a build tool that provides tasks for creating, compiling, and testing
# Elixir projects, managing its dependencies, and more.
# https://github.com/hexpm/hex_web/blob/master/mix.exs
#
defmodule PlugExample.Mixfile do
# In order to configure Mix, a developer needs to use Mix.Project in a module
# and define a function named project that returns a keyword list with
# configuration.
# http://elixir-lang.org/docs/stable/mix/Mix.Project.html
use Mix.Project
# Configure project.
def project do
[app: :Router,
version: "0.0.1",
elixir: "~> 1.2",
deps: deps]
end
#
# Returns applications that should be started.
#
# In OTP, application denotes a component implementing some specific
# functionality, that can be started and stopped as a unit, and which can be
# re-used in other systems as well.
# http://erlang.org/doc/man/application.html
#
def application do
[
applications: [:logger, :plug], # 3rd-party applications
mod: {PlugExample.Supervisor, []} # own application
]
end
#
# Returns project dependencies:
# https://hex.pm/
#
def deps do
[
{:cowboy, "~> 1.0.0"}, # Erlang web server
{:plug, "~> 1.0"} # Elixir's rack (Ruby), wsgi (Python), servlet (Java) API
]
end
end
```
Create lib/router.exs
```elixir
defmodule PlugExample.Router do
#
# Plug ships with a router that allows developers to quickly match on
# incoming requests and perform some action:
# https://hexdocs.pm/plug/readme.html#the-plug-router
#
use Plug.Router
#
# This module defines a Plug.Conn struct and the main functions for working with Plug connections.
# https://hexdocs.pm/plug/Plug.Conn.html
#
import Plug.Conn
# Logs request to STDOUT
plug Plug.Logger
# Matches request to a route
plug :match
# Dispatches request to a route
plug :dispatch
#
# Start a GenServer, i.e., a server instance:
#
# http://elixir-lang.org/getting-started/mix-otp/genserver.html
# https://blog.drewolson.org/understanding-gen-server/
#
def start_link do
# Cowboy adapter:
# https://hexdocs.pm/plug/Plug.Adapters.Cowboy.html
{:ok, _} = Plug.Adapters.Cowboy.http PlugExample.Router, []
end
#
# HTTP GET /
#
# Use conn.private to access route options:
# conn.private[:protected]
#
get "/", private: %{protected: false} do
conn |> send_resp(200, "Hello world")
end
get "/favicon.ico" do
conn |> send_resp(200, "LOL")
end
# Forward /about to another router's get "/" route
# forward "/about", to: PlugExample.About
#
# A catch-all route
#
match _ do
conn |> send_resp(404, "Not found")
end
end
```
Create lib/supervisor.ex
```elixir
#
# A supervisor is a process which supervises other processes, called child
# processes. Supervisors are used to build a hierarchical process structure
# called a supervision tree, a nice way to structure fault-tolerant applications.
#
# http://elixir-lang.org/docs/stable/elixir/Supervisor.html
#
defmodule PlugExample.Supervisor do
#
# In Elixir (actually, in Erlang/OTP), an application is a component
# implementing some specific functionality, that can be started and stopped as a
# unit, and which can be re-used in other systems.
# http://elixir-lang.org/docs/stable/elixir/Application.html
# http://erlang.org/doc/man/application.html
# http://erlang.org/doc/design_principles/applications.html
#
use Application
#
# The type argument passed to start/2 is usually :normal unless in a
# distributed setup where application takeovers and failovers are configured.
#
# start/2 typically returns {:ok, pid} or {:ok, pid, state} where pid
# identifies the supervision tree and state is the application state.
#
def start(_type, _args) do
#
# Convenience functions for defining a supervision specification.
# http://elixir-lang.org/docs/stable/elixir/Supervisor.Spec.html
#
import Supervisor.Spec, warn: false
# A list of children (workers or supervisors) to supervise
children = [
worker(PlugExample.Router, [])
]
#
# If a child process terminates, only that process is restarted:
# http://elixir-lang.org/docs/stable/elixir/Supervisor.html
#
opts = [strategy: :one_for_one, name: PlugExample.Supervisor]
#
# Start supervisor by passing the children to start_link/2.
# You may want to use a module-based supervisor.
Supervisor.start_link(children, opts)
end
end
```
Start the server:
```bash
$ mix deps.get
$ iex -S mix
```
Continue reading: [How to deploy an Elixir web application](http://snippets.aktagon.com/snippets/777-elixir-deployment).