Skip to content

フォルダ構成

📁 Elixir プロジェクトの標準的なフォルダ構成

Section titled “📁 Elixir プロジェクトの標準的なフォルダ構成”

Elixirでは、mix new コマンドを使ってプロジェクトを標準化します。これにより、開発者が共通の理解を持って作業できる、一貫したディレクトリ構造が生成されます。

my-app/
├── .formatter.exs # コードフォーマット設定
├── .gitignore # Gitの除外ファイル
├── config/ # 環境ごとの設定ファイル
│ ├── config.exs # 全環境共通のデフォルト設定
│ └── prod.exs # 本番環境固有の設定
├── lib/ # アプリケーションのコアとなるソースコード
│ └── my_app/
│ ├── application.ex # アプリケーション起動とスーパーバイザーツリー
│ ├── supervisor.ex # プロセスを監視・再起動する`Supervisor`
│ └── my_app.ex # アプリケーションの主要モジュール
├── priv/ # プライベートなアセット(マイグレーションなど)
├── test/ # テストコード
│ ├── my_app_test.exs # アプリケーションのテスト
│ └── test_helper.exs # テスト環境のセットアップ
└── mix.exs # プロジェクトの設定ファイル(依存関係、タスクなど)

この構造に慣れることで、新しいプロジェクトでもすぐに適応でき、効率的な開発が可能です。

ElixirWebフレームワークであるPhoenixは、Plugというライブラリを使用してミドルウェアを実装します。Plugは、リクエストが最終的なコントローラーに到達する前に、共通の処理(認証、ロギングなど)を実行するための仕様です。

Plugの実装例:認証ミドルウェア 🛡️

Section titled “Plugの実装例:認証ミドルウェア 🛡️”

Plugモジュールは、init/1call/2の2つの関数を実装する必要があります。

defmodule YourApp.AuthPlug do
import Plug.Conn
def init(opts), do: opts
def call(conn, _opts) do
# リクエストヘッダーから認証トークンを取得
case get_req_header(conn, "authorization") do
[token] when token == "my_secret_token" ->
# 認証成功、connにユーザー情報を追加
assign(conn, :current_user, %{id: 1, name: "Alice"})
_ ->
# 認証失敗、401レスポンスを返し、パイプラインを中断
conn |> send_resp(401, "Unauthorized") |> halt()
end
end
end

ルーターのパイプラインにこのミドルウェアを組み込むことで、特定のルートに共通の処理を適用できます。

defmodule YourApp.Router do
use Phoenix.Router
pipeline :api do
plug :accepts, ["json"]
plug YourApp.AuthPlug # 認証ミドルウェアを追加
end
scope "/api", YourApp.Web do
pipe_through :api
get "/profile", ProfileController, :show
end
end

🧠 Elixirのコアコンセプトとデザインパターン

Section titled “🧠 Elixirのコアコンセプトとデザインパターン”

Elixirは、オブジェクト指向ではなく、Erlang VM (BEAM)の並行処理と耐障害性を最大限に活用した独自の**OTPOpen Telecom Platform)**デザインパターンを持っています。

クライアント・サーバーモデルを実装するためのビヘイビアです。単一のプロセスで安全に状態を管理し、他のプロセスからのメッセージを処理します。キャッシュや外部リソースの接続プールなどで使用されます。

イメージ: メッセージを待つ「受付係」。

Let it crash」(クラッシュさせろ)の哲学に基づき、子プロセスを監視し、エラー発生時に自動的に再起動します。これにより、アプリケーション全体が停止することなく、高い回復能力を持つシステムを構築できます。

イメージ: 従業員(プロセス)を監督する「上司」。

プロセスをキーで登録し、そのプロセスIDを効率的に検索する機能です。分散環境で動的に生成されるプロセスを管理する際に便利です。

イメージ: プロセスと名前を結びつける「電話帳」。

🎨 BEAMPhoenixのアーキテクチャ

Section titled “🎨 BEAMとPhoenixのアーキテクチャ”

BEAMのアーキテクチャとプロセス間通信

Section titled “BEAMのアーキテクチャとプロセス間通信”

Elixirの強力な機能の秘密は、Erlangの仮想マシンであるBEAMにあります。BEAMは軽量なプロセスを多数作成し、これらはメモリを共有せずメッセージパッシングで通信します。これにより、1つのプロセスがクラッシュしても他のプロセスに影響を与えません。

Phoenixは、Plugを中心としたパイプラインモデルを採用しています。リクエストは一連のミドルウェアを通過し、コントローラーに渡されます。この構造により、リクエスト処理のロジックが明確に分離され、コードの可読性が向上します。

  • パターンマッチング: 関数の引数やデータ構造が特定のパターンに一致するかどうかを評価する機能。

  • パイプ演算子 (|>): 前の関数の結果を次の関数の最初の引数として渡すことで、関数呼び出しをチェーンでつなぎ、データフローを直感的に表現します。

これらの機能が組み合わさることで、Elixirは複雑な問題をシンプルかつ堅牢に解決できる、強力なツールとなっています。🚀