Elixir/Phoenixで作るリアルタイムWebアプリ入門

プログラミング言語

Elixirは、Erlang VMの上で動く関数型言語で、軽量プロセスによる超並行処理が強みです。Phoenixフレームワークと組み合わせれば、WebSocketによるリアルタイムWebを驚くほど少ないコードで実現できます。本記事では、Elixir × Phoenix入門を解説します。

Elixirの特徴

  • Erlang VM(BEAM)の信頼性・スケーラビリティを継承
  • 軽量プロセス(数百万本)で並行処理が容易
  • 関数型・パターンマッチ・パイプ演算子で読みやすい
  • OTPによるフォールトトレラント設計
  • マクロによるDSL構築が強力

環境構築

# Elixir + Erlangインストール
brew install elixir

# Phoenix生成器
mix archive.install hex phx_new

# 新規プロジェクト
mix phx.new my_app --database postgres
cd my_app
mix ecto.create
mix phx.server

Elixirの書き方サンプル

defmodule Math do
  def double(n), do: n * 2
  def half(n) when is_integer(n), do: div(n, 2)
end

[1, 2, 3]
|> Enum.map(&Math.double/1)
|> Enum.sum()
# 12

LiveViewでリアルタイムUI

Phoenix LiveViewは、サーバー側でレンダリングしWebSocketで差分配信するアプローチです。JSをほぼ書かずにリアクティブなUIが作れます。

defmodule MyAppWeb.CounterLive do
  use MyAppWeb, :live_view

  def mount(_params, _session, socket) do
    {:ok, assign(socket, count: 0)}
  end

  def handle_event("inc", _, socket) do
    {:noreply, update(socket, :count, &(&1 + 1))}
  end

  def render(assigns) do
    ~H"""
    Count: <%= @count %>
    <button phx-click="inc">+1</button>
    """
  end
end

Phoenix Channels(WebSocket)

チャット・通知などの双方向通信は、Phoenix Channelsで簡単に実装できます。スケール時にはBEAMが本領を発揮します。

OTPによる堅牢性

「Let it crash」哲学に基づき、SupervisorがクラッシュしたプロセスをWatchして再起動。電話交換機並みの稼働率を狙えるアーキテクチャです。

こんなプロジェクトに向く

  • 大量同時接続が必要なリアルタイムサービス(チャット・通知・IoT)
  • 高可用が要求されるサーバーサイド
  • 少人数で大規模ユーザーをさばきたい

まとめ

Elixir × Phoenixは「並行・並列・耐障害」を言語+フレームワークで一気に解決する選択肢です。LiveView + Channels + OTPを使えば、少人数でも本気のリアルタイムWebが作れます。少し変わった言語ですが、得意領域では他を圧倒する強みがあります。