mix phx.gen.json で生成し、Postmanで実行

#はじめに
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/ にアクセス
![Screenshot from 2021-10-04 18-31-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/d3bd03c9-2369-3bc2-eb9f-3c8fb6341662.png)

ブラウザで確認後、Phoenixは一度停止させます
Ctrl + C を２回で停止します

##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]を追加

``` lib/sample_web/router.ex
  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...

```
##ブラウザでapiが実行できることを確認
![Screenshot from 2021-10-04 19-04-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/3c394cab-9165-77ee-9548-1235681f51fc.png)

##Postmanを使って検証

####登録
・メソッド　```POST```
・URL　```http://localhost:4000/api/users```
・Bodyタグ→ROWを選択
・Text→JSONに変更
・内容　``` {"user": {"name":"ymn", "tel": "090-1234-1234"}} ```
・Sendをクリック

![Screenshot from 2021-10-04 19-14-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/b9a2148e-c0bf-1dba-e541-98fcb4215979.png)

####一覧
・メソッド　```GET```
・URL　```http://localhost:4000/api/users```
・Pransタグ
・Sendをクリック
![Screenshot from 2021-10-04 19-22-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/073b42ee-1267-9ace-5bc8-17d8c831ddcd.png)


####登録
・メソッド　```PATCH```
・URL　```http://localhost:4000/api/users/1```
・Bodyタグ→ROWを選択
・Text→JSONに変更
・内容　``` {"user": {"name":"abc", "tel": "777"}} ```
・Sendをクリック
![Screenshot from 2021-10-04 19-25-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/ba0fbb14-6a25-fef3-dd3d-cb5a8fec27d3.png)

####一覧で更新結果確認
・メソッド　```GET```
・URL　```http://localhost:4000/api/users```
・Pransタグ
・Sendをクリック
![Screenshot from 2021-10-04 19-27-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/89102eeb-96bc-9586-562e-d59a70950c5c.png)

####登録（追加）
・メソッド　```POST```
・URL　```http://localhost:4000/api/users```
・Bodyタグ→ROWを選択
・Text→JSONに変更
・内容　``` {"user": {"name":"ymn2", "tel": "090-1234-7777"}} ```
・Sendをクリック
![Screenshot from 2021-10-04 19-30-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/ea6ff515-fbe2-b0a0-3769-978267ea668b.png)

####IDが１のデータを表示
・メソッド　```GET```
・URL　```http://localhost:4000/api/users/1```
・Pransタグ
・Sendをクリック
![Screenshot from 2021-10-04 19-34-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/bfceb830-6bc2-d7c9-c7d9-72ad9710e63b.png)

####IDが１のデータを削除
・メソッド　```DELETE```
・URL　```http://localhost:4000/api/users/1```
・Pransタグ
・Sendをクリック
![Screenshot from 2021-10-04 19-35-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/2d9e2e15-89dd-0b69-1765-56fa29622b04.png)

####一覧で削除結果確認
・メソッド　```GET```
・URL　```http://localhost:4000/api/users```
・Pransタグ
・Sendをクリック
![Screenshot from 2021-10-04 19-36-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/315536df-e4ff-8b4f-9216-f6a2fbb4e24b.png)

##登録時のデータのフォーマットはどのようになっているかソースで確認

```lib/sample_web/controllers/user_controller.ex
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
```

```lib/sample/accounts/user.ex
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
```

この２つのソースから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"}} 
```
になります。