ゼロからElixir+Phoenixに入門する(1)
こんにちは、空のもりわきです。
今回、社内の検証用プロトタイプを作る機会がありまして、ElixirとPhoenixでの開発を行ってみました。
なぜElixirなのかというと、
- ゲーム会社で働いている友人からElixirいいよと薦められた
- 最近行った勉強会でも名前をよく耳にすることが多かった
- そろそろ新しい言語勉強しようと思った
ためです。
ElixirはRailsのコミッターであるJose Valim氏によって開発された関数型言語であり、Rubyライクに書くことができます。
Webアプリ用のフレームワークであるPhoenixもまたRailsぽく書くことができるためRubyやRailsを利用しているエンジニアならとっつきやすいのではと思います。
長くなってしまったので2回に分けて書いていきます!
プロトタイプのゴール
社内で利用するアプリケーション機能として以下を目指します。
本記事で2つめまでを言及しますが、認証までできれば3つ目と4つ目は時間をかけずに作ることができるはずです。
- 商品情報を登録できる管理画面を作る
- ユーザ登録を行い、emailでログインする
- 認証したユーザだけ商品情報の登録編集が可能になる
- 登録した商品情報を返却するAPIを用意する
環境構築
macに構築を行うため、brewでインストールを行っていきます。
elixirをインストールすることでmixコマンドが使えるようになります。
このmixはbundlerやyarnのようなパッケージ管理システムで、elixirパッケージのインストールやプロジェクトの管理を行うことができるようになります。
$ brew install elixir
$ elixir -v
Elixir 1.9.4 (compiled with Erlang/OTP 22) $ mix archive.install hex phx_new 1.4.11
DBはMySQLを利用したかったため、databaseオプションを指定してphoenixのプロジェクトを作成します。
$ mix phx.new phoenix_admin --database mysql
ちなみにdatabaseオプションなしの場合はPostgreSQLがデフォルトで選択されます。
なお、APIのみで構築する場合はno-htmlとno-webpackを指定することで作成できます。
$ mix phx.new phoenix_admin --database mysql --no-html --no-webpack
Accountコンテキストの作成
プロジェクトディレクトリに移動し、usersテーブルを作成します。
$ mix phx.gen.html Accounts User users name:string email:string:unique password:string
phx.gen.html により、controller, view, template, model, contextが1セットで作成されます。
lib/
phoenix_admin/
accounts.ex # コンテキスト
accounts/
user.ex # モデル
phoenix_admin_web/
channels/
controller/
template/
views/
コンテキストはDDDにおいて「境界づけられたコンテキスト」と表現されます。
例えば、同じuserモデルを利用するにしても、認証のための処理、ユーザ管理のための処理、ユーザが持っている権限の処理などに分けられると思います。
これらのメソッドをすべてuserモデルの中で定義してしまうと一気にモデルが大きくなってしまいます。これらを利用する側から見たグループ=コンテキストとして切り出してあげることで責務の分離が可能になります。
(小さなアプリの場合はまとめてもよいと思います。大きくなったら適切な名前をつけて分けてあげましょう。)
マイグレーション
ectoを利用してマイグレーションを行いますが、先にconfig/dev.exsを開いてDBの接続設定を行っておきます。
config :phoenix_admin, PhoenixAdmin.Repo,
username: "username",
password: "password",
database: "phoenix_admin_dev",
hostname: "localhost",
show_sensitive_data_on_connection_error: true,
pool_size: 10
設定ができれば、ecto.createでdatabaseを作成し、ecto.migrateでテーブルを作成します。
$ mix ecto.create
$ mix ecto.migrate
ルーティングの追加
lib/phoenix_admin_web/router.ex
を編集します。
resources を追加することで CRUDに対応したエンドポイントが自動的に生成されます。このあたりはRailsと同じですが、resource(単数形)に対応する記述は無いようなので自前で書いてあげる必要があります。
scope "/", PhoenixAdminWeb do
pipe_through :browser get "/", PageController, :index
resources "/users", UserController # 追加
end
phx.routes でルーティングが設定されているか確認します。
/users に対するリソースが生成されていますね!
$ mix phx.routes
page_path GET / PhoenixAdminWeb.PageController :index
user_path GET /users PhoenixAdminWeb.UserController :index
user_path GET /users/:id/edit PhoenixAdminWeb.UserController :edit
user_path GET /users/new PhoenixAdminWeb.UserController :new
user_path GET /users/:id PhoenixAdminWeb.UserController :show
user_path POST /users PhoenixAdminWeb.UserController :create
user_path PATCH /users/:id PhoenixAdminWeb.UserController :update
PUT /users/:id PhoenixAdminWeb.UserController :update
user_path DELETE /users/:id PhoenixAdminWeb.UserController :delete
起動
それではサーバを起動してみましょう。
以下のコマンドでアプリケーションサーバを起動し、http://localhost:4000 にアクセスすることで画面を見ることができます。
mix phx.server
/users にアクセスするとユーザの一覧・登録・編集・削除が可能になりました!
パスワードがinput type=”text” のままなので、template/user/form.htlm.eexを編集して password_input にしておきましょう。
<%= password_input f, :password %>
さらに、このままではパスワードが平文で保存されてしまいますので、hash化をしてあげる必要があります。
次回はguardianとargon2のパッケージを利用してemail+passwordでの認証処理とhash化を実装していきたいと思います。