備忘録

働きたくないでござる

Elixir の Umbrella プロジェクトで Phoenix アプリケーションを作成 (3)

前回: giraphme.hatenablog.com

今回はお待ちかね、 Phoenix アプリケーションを追加したいと思います。

構成

恒例(?) の構成を再掲。

$ tree .
.
├── apps
│   ├── us_core # DB関連のビジネスロジックをもった Elixir アプリケーション
│   └── us_api # REST API を提供する Phoenix アプリケーション ← イマココ
│   └── us_web # React を利用した View を提供する Phoenix アプリケーション
│   └── us_admin_web # 管理画面を提供する Phoenix アプリケーション

Phoenix アプリケーションを作成

構成にも書いていますが、 apps 下に us_api という名前で Phoenix アプリケーションを作成します。
なお、 archive.install や hex, rebar をインストールしている前提です。
(このブログでも以前取り上げましたが、クソ記事なのでリンクは載せません...)

$ cd apps
$ mix phx.new us_api

Database の設定を削除

us_api にはデータベースへの接続権限を持たせたくないので、自動で作られた設定を消していきます。
Phoenix 1.5.0 の時点では --database の設定を消すことはできないようです。phoenix/generator.ex at v1.3 · phoenixframework/phoenix · GitHub )

Phoenix のバージョンに依存して大きく作業手順がことなりそうなのと、 diff が大きすぎて書ききれないので要点だけ書くと、

  • apps/us_api/lib/us_api は不要なので全て消す。
  • apps/us_api/lib/us_api_web の中身は apps/us_api/lib/ に移動し、 UsApiWeb や us_api_web を UsApi 等に置換する。
  • Ecto で検索して適宜削除

地味面倒なので、試したいだけなら放置して進めてもいいかも......?

サーバー起動

一通り DB の設定を消せたかなと思ったら、以下のコマンドを入力してビルド・サーバーを起動してみましょう。

$ mix deps.get
$ cd assets && npm install
$ cd ..
$ mix compile
$ mix phx.new
=INFO REPORT==== 28-Sep-2017::00:11:30 ===
    application: logger
    exited: stopped
    type: temporary
** (Mix) Could not start application us_api: exited in: UsApi.Application.start(:normal, [])
    ** (EXIT) an exception was raised:
        ** (UndefinedFunctionError) function UsApi.Application.start/2 is undefined (module UsApi.Application is not available)
            UsApi.Application.start(:normal, [])
            (kernel) application_master.erl:273: :application_master.start_it_old/4

おそらくこの状況ではこのようなエラーが出ると思うので、以下のように修正していきます。

apps/lib/us_api/mix.exs

  def application do
    [
      mod: {UsApi.Application, []},
-     extra_applications: [:logger, :runtime_tools]
+     extra_applications: [
+       :logger, :gettext, :runtime_tools,
+       :phoenix, :phoenix_html, :cowboy,
+       :us_core,
      ]
    ]
  end

apps/blog_web/lib/application.ex

defmodule UsApi.Application do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec

    children = [
      supervisor(UsApi.Endpoint, []),
      # worker(UsApi.Worker, [arg1, arg2, arg3]),
    ]

    opts = [strategy: :one_for_one, name: UsApi.Supervisor]
    Supervisor.start_link(children, opts)
  end

  def config_change(changed, _new, removed) do
    UsApi.Endpoint.config_change(changed, removed)
    :ok
  end
end

``

  defp deps do
    [
      {:phoenix, "~> 1.3.0"},
      {:phoenix_pubsub, "~> 1.0"},
      {:phoenix_html, "~> 2.10"},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:gettext, "~> 0.11"},
-     {:cowboy, "~> 1.0"}
-     {:cowboy, "~> 1.0"},
+     {:us_core, in_umbrella: true}
    ]
  end
$ mix phx.new
$ mix phx.server
[info] Running UsApi.Endpoint with Cowboy using http://0.0.0.0:4000
00:22:06 - info: compiled 6 files into 2 files, copied 3 in 902 ms

めでたく phx.server が起動するようになりました。 ちなみに mix phx.server コマンドは、 apps/us_api でもプロジェクトのルートディレクトリでも実行可能です。


正直、DB の設定消すのとてもつらかった......。 でもプロジェクト内のファイルに一通り目を通すいい機会にもなったので、ぜひ一度お試しあれ(死亡フラグ