はじめに
僕は今までRuby(Rails)やPHPといった言語でWEBやゲームの開発をしてきたのですが、最近何か違うものに触りたいという思いでElixirを学び始めました。
そこで見つけたのが、 @koga1020 さんが書かれていた 『Phoenix + Vue.js入門』という記事でした。
今回は、この記事を参考にAPIサーバを構築し、初心者の自分が分からなかったところをメモとして、この記事に残していこうと思います。
1. プロジェクト作成
$ mix phx.new example_api_server_with_vuejs --no-brunch --database mysql
🔰 僕が引っかかったポイント 🔰
作成したプロジェクトと参考サイトのプロジェクトでディレクトリ構成が違いました。
原因は古いバージョンのPhoenixでプロジェクトを作成していたから
でした。
最初、僕は$ mix phoenix.new
コマンドを使用していたのですが、これだとどうやら1.2系の形でプロジェクトが構成されるようです。
(1.2と1.3で変更された内容に関してはこちらの記事を参考にしました。)
2. DB接続
プロジェクト作成時にオプションで--database mysql
を指定しているので、
config/dev.exs
の50行目が下記のようになっていると思います。
# Configure your database
config :example_api_server_with_vuejs, ExampleApiServerWithVuejs.Repo,
adapter: Ecto.Adapters.MySQL,
username: "root",
password: "",
database: "example_api_server_with_vuejs_dev",
hostname: "localhost",
pool_size: 10
自分のMySQLの情報に合わせて書き直してあげましょう。
3. API作成
3-1. 雛形ファイル作成
下記コマンドにより、まずは雛形となるJSONレスポンス用のController, View, Contextを作成します。
$ mix phx.gen.json Blog Article articles title:string body:text
🔰 僕が引っかかったポイント1 🔰
参考サイトには$ mix phx.gen.json
によりモデルを作成とあったので、モデル関連のファイルが作成されると思ったのですが、なにやらControllerやViewまで作成されている…
むむむ?と思い、$ mix help
で調べてみると、下記のような説明がされていました。
mix phx.gen.json # Generates controller, views, and context for a JSON resource
なるほどなるほど、$ mix phx.gen.json
はJSONレスポンス用のいろいろを作成してくれるコマンドだったんですね!すごい便利ですね!
🔰 僕が引っかかったポイント2 🔰
上記の引っかかったポイント1について調べるとき、公式リファレンスを見たのですが、目的のものが見つけられなかった。(僕の見方が悪い可能性 ”大”)
そんなときに役に立ったのが $ mix help
コマンドでした。
このコマンドを使うと、mixで使用可能なコマンド一覧とそれぞれの簡単な説明を出してくれます。有能!
3-2. テーブル作成
前節のコマンド実行時にマイグレーションファイルも作られているので、下記コマンドでテーブルを作成します。
$ mix ecto.migrate
3-3. ルーティング設定
下記のとおりルーティングを設定。
defmodule ExampleApiServerWithVuejsWeb.Router do
use ExampleApiServerWithVuejsWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
# plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", ExampleApiServerWithVuejsWeb do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
end
# Scopes for API
scope "/api", ExampleApiServerWithVuejsWeb do
pipe_through :api
resources "/articles", ArticleController, except: [:new, :edit]
end
end
-
scope "/api", HogeFoo do ~ end
という記述により、このdo ~ end
内で設定したルーティング(URL)には先頭に/api
が追加されます。 -
ルーティング設定では、
get "/", PageController, :index
のように各リソースに対してHTTPメソッドをひとつひとつ定義する方法もありますが、今回はresources
によってarticles
に対して主要なHTTPメソッド(処理)を一気に定義してあげます。
Phoenixのコマンドでルーティングを確認すると下記のようになっていると思います。
$ mix phx.routes
page_path GET / ExampleApiServerWithVuejsWeb.PageController :index
article_path GET /api/articles ExampleApiServerWithVuejsWeb.ArticleController :index
article_path GET /api/articles/:id ExampleApiServerWithVuejsWeb.ArticleController :show
article_path POST /api/articles ExampleApiServerWithVuejsWeb.ArticleController :create
article_path PATCH /api/articles/:id ExampleApiServerWithVuejsWeb.ArticleController :update
PUT /api/articles/:id ExampleApiServerWithVuejsWeb.ArticleController :update
article_path DELETE /api/articles/:id ExampleApiServerWithVuejsWeb.ArticleController :delete
🔰 僕が引っかかったポイント 🔰
参考サイトでは、plug :protect_from_forgery
がコメントアウトされています。
これはなんでしょうか…。分からずでした。誰か教えてください!
(名前から察するに、何かしらの悪意ある偽装をprotectするものですね笑)
ただ、
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
# plug :protect_from_forgery
plug :put_secure_browser_headers
end
この部分は
scope "/", ExampleApiServerWithVuejsWeb do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
end
こちらのscope "/"
用に定義されたパイプラインなので、今回のAPIには一切関係ないです。
Pipelineに関してはこちらの記事で、Plugに関してはこちらの記事である程度理解できました。
4. テスト
方法はなんでもいいですが、http://0.0.0.0:4000/api/articles
にGETリクエストを投げてみましょう。
(僕はPostmanを利用しました)
下記のようなレスポンスがあればOKです。
{
"data": []
}
空レスポンスを見ていてもつまらないので、新しいArticleを追加してみましょう。
Articleを追加するには、http://0.0.0.0:4000/api/articles
にPOSTリクエストを投げればOKです。
そのさいのBodyは以下のようにします。(JSON形式)
{
"article": {
"title": "テスト題目",
"body": "テスト本文"
}
}
リクエストを投げると、以下のようなレスポンスが返ってきます。
{
"data": {
"title": "テスト題目",
"id": 1,
"body": "テスト本文"
}
}
では、ここでもう一度http://0.0.0.0:4000/api/articles
にGETリクエストを投げてみましょう。
{
"data": [
{
"title": "テスト題目",
"id": 1,
"body": "テスト本文"
}
]
}
先程のArticleが追加されてますね!
さらにArticleを追加してみて、GETリクエストを投げると、以下のようになります。
{
"data": [
{
"title": "テスト題目",
"id": 1,
"body": "テスト本文"
},
{
"title": "テスト題目2",
"id": 2,
"body": "テスト本文2"
},
{
"title": "テスト題目3",
"id": 3,
"body": "テスト本文3"
}
]
}
OKOK!
これで、Elixir + Phoenix + MySQL でAPIサーバができました。
簡単でしたね!
おわりに
ElixirはRailsのコアコミッターであるJose Valimさんによって作られているため、Rails経験者の僕にはすんなりと入門できました。
ただ、今回はコマンドで生成したコントローラで全てやってしまっています。
本来であれば、DDDのコンテキストという概念を取り入れた処理の書き方などがあるそうです。
Elixir + Phoenixをやっていく上では、そこも学んでいかないと思っています。
今後もがんばっていきます!
参考サイトでは、ここからVue.jsを使ったフロント側の実装に入りますが、そこはまた別記事で書きます。(多分…)
追記(2018/11/18):
個人ブログ始めました。
よかったらこちらもどうぞ!