#はじめに
Elixir + Phoenixでjsonで返却するAPIを作ってみます。
##この記事実行時の環境
$ elixir -v
Erlang/OTP 24 [erts-12.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]
Elixir 1.12.2 (compiled with Erlang/OTP 22)
$ mix phx.new -v
Phoenix installer v1.6.0
$ psql
psql (12.8 (Ubuntu 12.8-0ubuntu0.20.04.1))
Type "help" for help.
##プロジェクトを作成
$ mix phx.new sample
* creating sample/config/config.exs
* creating sample/config/dev.exs
〜 中略 〜
* creating sample/priv/static/images/phoenix.png
* creating sample/priv/static/favicon.ico
Fetch and install dependencies? [Yn] y
* running mix deps.get
* running mix deps.compile
We are almost there! The following steps are missing:
$ cd sample
Then configure your database in config/dev.exs and run:
$ mix ecto.create
Start your Phoenix app with:
$ mix phx.server
You can also run your app inside IEx (Interactive Elixir) as:
$ iex -S mix phx.server
##Phoenix立ち上がるまで確認
$ cd sample
$ mix ecto.create
Compiling 14 files (.ex)
Generated sample app
The database for Sample.Repo has been created
$ mix phx.server
[info] Running SampleWeb.Endpoint with cowboy 2.9.0 at 127.0.0.1:4000 (http)
[debug] Downloading esbuild from https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.12.18.tgz
[info] Access SampleWeb.Endpoint at http://localhost:4000
[watch] build finished, watching for changes...
##ブラウザで確認
http://localhost:4000/ にアクセス
ブラウザで確認後、Phoenixは一度停止させます
Ctrl + C を2回で停止します
##mix phx.gen.jsonを実行
$ mix phx.gen.json Accounts User users name:string tel:string
* creating lib/sample_web/controllers/user_controller.ex
〜 中略 〜
* injecting test/support/fixtures/accounts_fixtures.ex
Add the resource to your :api scope in lib/sample_web/router.ex:
resources "/users", UserController, except: [:new, :edit]
Remember to update your repository by running migrations:
$ mix ecto.migrate
##router.exを修正
・scope "/api", SampleWeb doから始まる部分のコメントを解除
・resources "/users", UserController, except: [:new, :edit]を追加
use SampleWeb, :router
# 〜 中略 〜
scope "/", SampleWeb do
pipe_through :browser
get "/", PageController, :index
end
#ここからが修正対象
# Other scopes may use custom stacks.
scope "/api", SampleWeb do
pipe_through :api
resources "/users", UserController, except: [:new, :edit]
end
# 〜 中略 〜
end
#migrate、再度Phoenixで起動確認
$ mix ecto.migrate
Compiling 7 files (.ex)
Generated sample app
19:01:42.287 [info] == Running 20211004094949 Sample.Repo.Migrations.CreateUsers.change/0 forward
19:01:42.291 [info] create table users
19:01:42.303 [info] == Migrated 20211004094949 in 0.0s
$ mix phx.server
[info] Running SampleWeb.Endpoint with cowboy 2.9.0 at 127.0.0.1:4000 (http)
[info] Access SampleWeb.Endpoint at http://localhost:4000
[watch] build finished, watching for changes...
##Postmanを使って検証
####登録
・メソッド POST
・URL http://localhost:4000/api/users
・Bodyタグ→ROWを選択
・Text→JSONに変更
・内容 {"user": {"name":"ymn", "tel": "090-1234-1234"}}
・Sendをクリック
####一覧
・メソッド GET
・URL http://localhost:4000/api/users
・Pransタグ
・Sendをクリック
####登録
・メソッド PATCH
・URL http://localhost:4000/api/users/1
・Bodyタグ→ROWを選択
・Text→JSONに変更
・内容 {"user": {"name":"abc", "tel": "777"}}
・Sendをクリック
####一覧で更新結果確認
・メソッド GET
・URL http://localhost:4000/api/users
・Pransタグ
・Sendをクリック
####登録(追加)
・メソッド POST
・URL http://localhost:4000/api/users
・Bodyタグ→ROWを選択
・Text→JSONに変更
・内容 {"user": {"name":"ymn2", "tel": "090-1234-7777"}}
・Sendをクリック
####IDが1のデータを表示
・メソッド GET
・URL http://localhost:4000/api/users/1
・Pransタグ
・Sendをクリック
####IDが1のデータを削除
・メソッド DELETE
・URL http://localhost:4000/api/users/1
・Pransタグ
・Sendをクリック
####一覧で削除結果確認
・メソッド GET
・URL http://localhost:4000/api/users
・Pransタグ
・Sendをクリック
##登録時のデータのフォーマットはどのようになっているかソースで確認
defmodule SampleWeb.UserController do
use SampleWeb, :controller
# 〜 中略 〜
def create(conn, %{"user" => user_params}) do
with {:ok, %User{} = user} <- Accounts.create_user(user_params) do
conn
|> put_status(:created)
|> put_resp_header("location", Routes.user_path(conn, :show, user))
|> render("show.json", user: user)
end
end
# 〜 中略 〜
end
defmodule Sample.Accounts.User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field :name, :string
field :tel, :string
timestamps()
end
@doc false
def changeset(user, attrs) do
user
|> cast(attrs, [:name, :tel])
|> validate_required([:name, :tel])
end
end
この2つのソースからjsonの送るデータ形式がわかります。
user_controller.exの
def create(conn, %{"user" => user_params}) do
を仮に説明の為に
def create(conn, %{"①" => user_params}) do
user.exの
schema "users" do
field :name, :string
field :tel, :string
timestamps()
end
を仮に説明の為に
schema "users" do
field :②, :string
field :③, :string
timestamps()
end
とした場合追加のJsonの内容は
{"①": {"②":"ymn2", "③": "090-1234-7777"}}
になります。