Skip to main content

Elixirで簡単なREST APIを作る

Elixirで簡単なREST APIを作る方法のメモ

プロジェクト作成

webpackは不要なので--no-webpackを付けて実行

$ mix phx.new hello --no-webpack
$ cd hello

データベース作成

デフォルトではPostgreSQLを使うので事前にPostgreSQLを起動しておき、次のコマンドを実行する。なお、 PostgreSQLへの接続情報はconfig/dev.exs(devモードの場合)に記述してあるので必要に応じて変更する。

$ mix ecto.create

API作成

ここではnameageを持つUser APIを作る。

$ mix phx.gen.json Accounts User users name:string age:integer

usersテーブルを作成するためマイグレートする。

$ mix ecto.migrate

lib/hello_web/router.exの以下の部分のコメント削除し、resources "/users"...の1行を追加する。これにより/api/usersでアクセス可能となる。

# Other scopes may use custom stacks.
scope "/api", HelloWeb do
  pipe_through :api
  # この行を追加
  resources "/users", UserController, only: [:index, :show, :create, :update] 
end

API起動

次のコマンドで起動する。

$ iex -S mix phx.server                                  
Erlang/OTP 22 [erts-10.6.4] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]
[info] Running HelloWeb.Endpoint with cowboy 2.7.0 at 0.0.0.0:4000 (http)
[info] Access HelloWeb.Endpoint at http://localhost:4000
Interactive Elixir (1.10.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

確認

ユーザーを登録してみる。

$ curl -X POST -H "Content-type: application/json" -d '{"user":{"name":"tom","age": 20}}' http://localhost:4000/api/users

登録したユーザーを取得してみる。

$ curl  http://localhost:4000/api/users/1
{"data":{"age":20,"id":1,"name":"tom"}}

カスタマイズ

デフォルトではユーザー登録のリクエストメッセージは{"user":{"name":"tom","age": 20}}となり、"user"をつける必要がある。これを{"name":"tom","age": 20}で登録できるようにしたい。

そのためには、lib/hello_web/controllers/user_controller.exを次のように書き換えればよい。

# 変更前
def create(conn, %{"user" => user_params})
# 変更後
def create(conn, user_params)

またユーザー取得時には、{"data":{"age":20,"id":1,"name":"tom"}}となり、"data"がつくがこれを{"age":20,"id":1,"name":"tom"}にしたい。

そのためには、lib/hello_web/views/user_view.exを次のように修正すればよい。

def render("index.json", %{users: users}) do
  # %{data: render_many(users, UserView, "user.json")} # コメントアウト
  render_many(users, UserView, "user.json") # このように書き換える
end

def render("show.json", %{user: user}) do
  # %{data: render_one(user, UserView, "user.json")} # コメントアウト
  render_one(user, UserView, "user.json") # このように書き換える
end

リクエストを投げて確認する。

$ curl -X POST -H "Content-type: application/json" -d '{"name":"joe","age": 30}' http://localhost:4000/api/users
$ curl http://localhost:4000/api/users/2
{"age":30,"id":2,"name":"joe"}

ちゃんと変わってますね。

参考情報

https://hexdocs.pm/phoenix/up_and_running.html#content
https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Json.html
https://hexdocs.pm/phoenix/1.4.17/phoenix_mix_tasks.html#content