CowboyとElixirで動的ページを表示する

ElixirとCowboyを使って、Webページを表示するための記事です。
解説が間違っていた場合には、コメントか@hayabusa333にご連絡くださると嬉しいです。

# Cowboy is 何?
CowboyはErlangで書かれた小さくて高速なモジュラー形式のHTTPサーバです。
今回はElixirでCowboyを使い動的ページを表示したいと思います。

静的ページを表示するは下記より
CowboyとElixirで静的ページを表示する

# 実行環境
OS:OS X Yosemite
Erlang:Eshell V6.5, OTP-Version 18
Elixir:v1.0.4

# Cowboyで動的なページを表示するための新規プロジェクトの作成

$ mix new dynamic_hello_world --sup
$ cd dynamic_hello_world

# HexにてCowboyをインストールするために設定ファイルの記載を行う

$ vim mix.exs

mix.exsの内容は下記となります。

defmodule StaticHelloWorld.Mixfile do
  use Mix.Project

  def project do
    [app: :static_hello_world,
     version: "0.0.1",
     elixir: "~> 1.0",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps]
  end

  # Configuration for the OTP application
  #
  # Type `mix help compile.app` for more information
  def application do
    # cowboy, ranch をライブラリとして使用することを宣言します
    [applications: [:logger, :cowboy, :ranch],
    # mod: にて supervision tree の 中に DynamicHelloWorld が登録されます
     mod: {DynamicHelloWorld, []}]
  end

  # Dependencies can be Hex packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
  #
  # Type `mix help deps` for more examples and options
  defp deps do
    [{ :cowboy, "1.0.0" }]
  end
end

# Cowboyにて動的ページを表示するためにCowboyの起動に関するコードを記載する
Supervisorの記載

$ vim lib/supervisor.ex

# 実装内容
defmodule DynamicHelloWorld.Supervisor do
  use Supervisor

  def start_link(_) do
    {:ok, sup} = Supervisor.start_link(__MODULE__, [], name: :supervisor)
  end

  # supervisorモジュールを起動する際に init/1 を渡す必要がある
  def init(_) do
    processes = []
    # Supervisorの戦略を決定します。
    # one_for_oneは自分自身がダメになったら他人に影響されず
    # 自分自身を再起動するという戦略です。
    {:ok, {{:one_for_one, 10, 10}, processes}}
  end

end

今回の動的ページを表示するアプリケーションのMainを記載

$ vim lib/dynamic_hello_world.ex

# 実装内容
defmodule DynamicHelloWorld do
  def start(_type, _args) do
    # Cowboyのルーティング機能を定義
    dispatch = :cowboy_router.compile([
      { :_,
        [
          # http://localhost:8080/ にアクセスしてきた場合に、DynamicPageHandler を呼び出すように定義
          {"/", DynamicPageHandler, []}
      ]}
    ])
    # Cowboyを起動とともに起動内容を定義
    { :ok, _ } = :cowboy.start_http(:http, 100, [{:port, 8080}], [{ :env, [{:dispatch, dispatch}]}] )

  end
end

リクエストにたいしてリプライを行うハンドラーの記載

vim lib/dynamic_page_handler.ex

# 実装内容
defmodule DynamicPageHandler do
  def init(_type, req, []) do
    {:ok, req, :no_state}
  end

  # http://localhost:8080/ へリクエストがきた際のレスポンスを作成する
  def handle(request, state) do
    # 文字列型を定義
    dynamic = "Dynamic"
    # リクエスト内容を定義し、上記の文字列型の変数の中身をレスポンスに含めるように記載
    # 変数の内容を使えることにより動的にページの内容を変更することができる
    { :ok, reply } = :cowboy_req.reply( 200, [{"content-type", "text/html"}], "#{dynamic} Hello World", request)
    {:ok, reply, state}
  end

  def terminate(reason, request, state) do
    :ok
  end
end

# Cowboyを起動する

$ mix deps.get
$ mix run --no-halt

ブラウザにて http://localhost:8080 にアクセスし
DynamicHelloWorldと表示されたら成功です。

# まとめ
今回はElixirでCowboyを使用し動的なWebページを表示してみました。
Cowboyがいかにしてリクエストに対して返信を行っているのか見えてきたところがあるでしょうか?

それでは皆さま、良いElixirライフを