読者です 読者をやめる 読者になる 読者になる

くりふぃの日記

プログラミングとかのメモ書きとかに使えたらいいなぁ。

Elixir/Phoenixで適当になにか作る

なんで?

Elixirの存在は今よりもっと前から知っていたんだけど、その時は特に興味も抱かずに深く調べなかった。

最近になって職場でElixirの名前が出てきたので何なのか興味を持ちだしてRubyっぽい関数パラダイムの言語というところに惹かれてちょっと触ってみようかなと。

何作る?

具体的に決めてはいないがJSON APIで短いテキストをやり取りするアプリを作る。なにせ全く知らない言語でパラダイムも今までほとんど触れたことのない関数型なのでまともなものは作れないから。

環境

今回の環境を以下に列挙する。

プロジェクト作成

今回はPhoenixFrameworkを利用して作っていこうと思う。

Phoenixの新規プロジェクトを作成するコマンドは以下の通り。

mix phoenix.new PROJECT_NAME

PROJECT_NAMEは任意のプロジェクト名を入力する。自分の環境ではposted_strという名前で作ってます。

コマンドを入力するとプロジェクト名のディレクトリ以下にファイルが生成される。その後コマンド

リソース設計

RESTっぽくリソースの定義。とりあえずユーザーと登録テキストの2つがあればいろいろできるかな。

認証系は今は無視するとしてユーザー情報としてユーザー名。それに紐づく登録テキスト。

とりあえずectoを使ってPostgreSQLに保管しておくことにする。

モデル・コントローラ・ビュー生成

リソースに基づいて骨組みとなるファイルを生成する。Phoenixで定義されているMIXタスクによって行うことができpnoenix.gen.jsonというタスクで骨組みの生成ができる。

他にも以下の様なタスクがあり自動的にファイルを生成してくれる。

  • phoenix.gen.html(HTMLページ用の骨組み生成)
  • phoenix.gen.model(モデルの生成)
  • phoenix.gen.channel(チャンネルの生成)

チャンネルはリアルタイムWEB用に用いるWebsocketなどのインターフェイスのようだ。詳しくはわからない。

早速ユーザー情報と登録テキストの骨組み生成してみる。

mix phoenix.gen.json User users username:string
mix phoenix.gen.json Post posts user_id:integer post:text

骨組み生成はこれで完了。

ルーティング定義

骨組みを生成しただけではルーティングの定義までは行ってくれないようなので、生成時のメッセージを元にルーティングを定義する。

特に難しく考えずメッセージに書かれた内容をコピペする。

これをしないとコンパイルエラーが発生する。

ルーティング確認

現在のルーティングの定義を確認するためのMIXタスクがPhoenixphoenix.routesとして定義されている。

どのようなルーティング定義になっているかを実際に確認してみる。

mix phoenix.routes

出力結果は省略する。以下の情報が確認できるかと思う。

  • ルーティング名(ソースコード上でパスを返却する関数となる)
  • HTTPメソッド
  • パス
  • モジュール名(呼び出されるモジュール名)
  • アクション名(呼び出される関数名)

マイグレーション

骨組みを生成したらモデルの内容を実際にDBに反映させる必要がある。マイグレーションPhoenixで使われているDBライブラリのEctoによって行う。

mix ecto.create
mix ecto.migrate

mix ecto.createでデータベースを作成し、mix ecto.migrateスキーマ定義が更新される。

リレーション定義

ユーザー情報と登録テキストは一対多の関係である。この関係をモデルに定義する。

Railsとだいたい同じ。第二引数にモジュールを指定する必要があるのと、belongs_toでは外部キーを指定して上げる必要が有ることが異なる。

belongs_toはフィールド定義も兼ねているようで、モデル生成で定義された外部キーとなるレコードは定義を消してあげる必要がある。消さないと定義の重複でエラーとなる。

動作確認

これで一通り動作するまでになったと思われるので、ユーザー情報を登録してテキストを投稿するまで確認してみる。

動作確認用のサーバを立ち上げるにはphoenix.serverタスクを実行する。

mix phoenix.server

これでlocalhost:4000にHTTPリクエストを受け付けることができるようになる。

ユーザー情報登録

テスト用のデータは何も用意していないので作成したJSON APIを用いて直接データを登録する。

ユーザー情報登録はUserController#createであり、ルーティングはPOST /usersと定義されている。ここに何らかの手段を用いてJSONデータをPOSTする。

PhoenixではContent-typeをapplication/jsonでデータを送るとマッピングしてControllerのActionとして定義した関数の第二引数にバインドされる。

phoenix.gen.jsonタスクで生成したUserControllerはパターンマッチングによって"user"をキーとした値以外を受け付けないようになっている。そのため以下の様なJSONデータを送信する必要がある。

{"user": {"username": "name"}}

以上のデータを送信することでデータベースにユーザー情報が登録される。

データが作成されたため、GET /usersで登録したデータの一覧が取得できる。

{"data":[{"username":"test","id":1}]}

当然、作成したユーザー情報をIDで指定して取得もできる。

{"data":{"username":"test","id":1}}

登録テキスト投稿

登録テキストの投稿も同様に行える。

{"post": {"user_id": 1, "post": "テキスト"}}

総括

これといったコードは書いていないが簡単なリソースのCRAD処理はPhoenixの機能で簡単に実現できた。ここらへんは完全にRails同様である。

ここから少しずつコードを書いていって何らかのアプリと呼べるようなものを作っていきたいと思う。

その前に自動生成されたソースコードの読み解きを行う必要がありそうなので、次の機会に挙動から分かる範囲で読み解いていこうと思う。