2016年7月31日日曜日

「超高速なJSON APIをElixirフレームワークのPhoenixでビルドしてテストしよう」のアップデート

「超高速なJSON APIをElixirフレームワークのPhoenixでビルドしてテストしよう」

上の記事は、Elixir/PhoenixでJSON APIを作るガイドです。

実際には、mixのタスクを使って作るのが効率的ですが、TDD的にテストコードを書いて、テストを通すようにコードを作っていくため、PhoenixでのJSON APIの扱いをステップバイステップで理解することができます。

↓こちらはmix タスクを使った例

http://qiita.com/FL4TLiN3/items/41ca80cdbfca1956ed78

↓こちらはバージョニングした例

http://qiita.com/5t111111/items/79b861349f0e1ffae1e9

ただ、現在Phoenixは活発に開発が進んでいるため、一部コードが動かなくなっています。

今回、以下のバージョンで動くようにしました。

% iex -v
Erlang/OTP 18 [erts-7.3] [source-d2a6d81] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]

IEx 1.2.3
% mix -v
Mix 1.2.3
  defp deps do
    [{:phoenix, "~> 1.1.4"},
     {:postgrex, ">= 0.0.0"},
     {:phoenix_ecto, "~> 2.0"},
     {:phoenix_html, "~> 2.4"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.9"},
     {:cowboy, "~> 1.0"}]
  end

変更箇所

mix ecto migration

add/1 は廃止。型を指定する必要がある

priv/repo/migrations/XXX_create_contacts.exs

-      add :name
-      add :phone
+      add :name, :string
+      add :phone, :string

確認

$ psql -U postgres -W
# database確認
postgres# /l
# テーブル定義確認
postgres# /d table_name

transaction のエラー

以下のerrorが出る。

理由は、現行だとtest_helper.exsが自動でtransactionをスタートするコードになっている。

** (RuntimeError) cannot begin test transaction because we are already inside one

以下を削除する

test/controllers/contact_controller_test.exs

  setup do
    SQL.begin_test_transaction(Repo)

    on_exit fn ->
      SQL.rollback_test_transaction(Repo)
    end
  end

ConnCaseモジュールを使用する(test/support/conn_case.ex(自動生成))

test/controllers/contact_controller_test.exs

-  use ExUnit.Case, async: false
-  use Plug.Test
+  use HelloPhoenixConnCase, async: false
  alias HelloPhoenix.Contact
  alias HelloPhoenix.Repo
  alias Ecto.Adapters.SQL

Poison.encode!できない

Repo.insert の戻り値が{:ok, ...}で戻ってくるため、Poinson.encodeに失敗する

test/controllers/contact_controller_test.exs

       |> List.wrap
+      |> Enum.map(&(elem(&1, 1))) 
       |> Poison.encode!

controller内にplug :actionがあると、responseが重複する

以下のエラーが出る。

** (Plug.Conn.AlreadySentError) the response was already sent

原因はここ参考。 https://github.com/phoenixframework/phoenix/issues/888 http://stackoverflow.com/questions/32448308/phoenix-elixir-ejabberd-response-already-sent-error

plug :action を削除

HelloPhoenix.ContactController

-     plug :action

clean upについて

  • そのまま動きます。
  • 場所はtest_helper.ex, test/support/conn_case.exどちらでもOK
  • modelはテストケースで直接読み込んだ方がいいかもしれません

Elixir/Phoenixの活用方法としては、APIサーバーとしての利用がまず考えられると思います。

その入り口として、動かしてみたい方は参考にどうぞ

0 件のコメント:

コメントを投稿