LoginSignup
14
4

Elixir入門からPhoenixでCRUD + SPAまで

Last updated at Posted at 2023-12-08

この記事は「Elixir Advent Calendar 2023 9日目の記事です

piyoyo_exのMotzです。
普段はTypeScript,React,Go,Pythonなどを書くことが多いです。
今回Elixirに入門してPhoenixで簡単なSPAを作成したので、その際の開発体験や感想を共有できればと思います。

Elixir,Phoenixについて

Elixir

Elixir (エリクサー) は並行処理の機能や関数型といった特徴を持つ、Erlangの仮想マシン (BEAM) 上で動作するコンピュータプログラミング言語である。ElixirはErlangで実装されているため、分散システム、耐障害性、ソフトリアルタイムシステム等の機能を使用することができるが、拡張機能として、マクロを使ったメタプログラミング、そしてポリモーフィズムなどのプログラミング・パラダイムもプロトコルを介して実装されている
wikipedia Elixir

並行処理、関数型、分散システム、メタプログラミング...なにやら好奇心をそそられる単語が並んでいますね🤔
そして登場時期は2012年 新しいです!

Phoenix

Phoenixは、「開発者の高い生産性」と「高いアプリケーションパフォーマンス」を両立します。 また、リアルタイム機能を実装するためのチャネルや、非常に高速なプリコンパイル済みテンプレートなど、いくつかの興味深い新しい工夫が施されています。
Phoenix v1.6 hexdocs 日本語訳

開発生産性とパフォーマンスの両立とは夢が詰まってますね🥳

現在Elixir Advent Calendar 2023も盛りあがっています!

動作環境

Elixirは1.15.7,Poenixは1.7.10を使用しています。

elixir -v
#Elixir 1.15.7 (compiled with Erlang/OTP 26)
mix.exs
{:phoenix, "~> 1.7.10"},

Hello Phoenix !

今回はDBの設定や起動の手間を省くためにやSqlite3を使用しますが、Postgres、Mysqlを使用する場合は以下のガイドを参考してください。

sqlite3を使用する場合

mix phx.new <アプリ名> 
でPhoenixでphoenixアプリケーションを作成できます。以下実行例

mix phx.new hello

* creating hello/lib/hello/application.ex
* creating hello/lib/hello.ex
* creating hello/lib/hello_web/controllers/error_json.ex
~~~~~~~~~~~~~~~~~~略~~~~~~~~~~~~~~~~~~~~~~
* extracting hello/assets/vendor/heroicons/optimized

Fetch and install dependencies? [Yn] Y
* running mix deps.get
* running mix assets.setup
* running mix deps.compile

We are almost there! The following steps are missing:

    $ cd hello

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

その後は表示されているコマンドを順に実行し、DBのためのファイル作成とサーバを起動します。

cd hello
mix ecto.create
iex -S phx.server #インタラクティブシェルを開きながらサーバーを起動します

起動できたら
http://localhost:4000へアクセスしましょう。
何回やっても初めてのHello Worldはドキドキですよね!

スクリーンショット 2023-12-09 3.21.38.png

PhoenixでCRUD + SPA

PhoenixのScaffoldingは以下のパターンで使用できます。
mix phx.gen.live <コンテキスト> <スキーマ> <テーブル名> <カラム名>:<型> ...


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

* creating lib/hello_web/live/user_live/show.ex
* creating lib/hello_web/live/user_live/index.ex
* creating lib/hello_web/live/user_live/form_component.ex
* creating lib/hello_web/live/user_live/index.html.heex
* creating lib/hello_web/live/user_live/show.html.heex
* creating test/hello_web/live/user_live_test.exs
* creating lib/hello/accounts/user.ex
* creating priv/repo/migrations/20231208193941_create_users.exs
* creating lib/hello/accounts.ex
* injecting lib/hello/accounts.ex
* creating test/hello/accounts_test.exs
* injecting test/hello/accounts_test.exs
* creating test/support/fixtures/accounts_fixtures.ex
* injecting test/support/fixtures/accounts_fixtures.ex

Add the live routes to your browser scope in lib/hello_web/router.ex:

    live "/users", UserLive.Index, :index
    live "/users/new", UserLive.Index, :new
    live "/users/:id/edit", UserLive.Index, :edit

    live "/users/:id", UserLive.Show, :show
    live "/users/:id/show/edit", UserLive.Show, :edit


Remember to update your repository by running migrations:

    $ mix ecto.migrate

phx.gen.liveの結果に記述の通りlib/hello_web/router.exファイルを編集して、migrateしましょう。

lib/hello_web/router.ex
~~~~~~~
  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", HelloWeb do
    pipe_through :browser
    live "/users", UserLive.Index, :index
    live "/users/new", UserLive.Index, :new
    live "/users/:id/edit", UserLive.Index, :edit

    live "/users/:id", UserLive.Show, :show
    live "/users/:id/show/edit", UserLive.Show, :edit

    get "/", PageController, :home
  end
~~~~~~~
mix ecto.migrate
phx server

ここまで実行すればhttp://localhost:4000/users
にアクセスしましょう。心ゆくまでSPAを堪能してください

スクリーンショット 2023-12-09 4.43.28.png

Elixir + Phoenixのここがスゴイ

主に開発していて良いと感じた部分です。Elixirの並行処理や高可用性などパフォーマンスに関する非機能要件は含んでいません(ここも良いらしい)。

  • mixが標準搭載: 他の言語ではパッケージ管理ツールが別になっているものも多いですよね。特にnpm、pipなどで入門者はつまづきがちですよね。
  • Phoenix LiveView: リアルタイムなWeb UI を作成できるPhoenixの機能です。Webosocketプロトコルを使用しているので一般的にhttpよりも少ないヘッダーで通信できます。フロントでの記述量を大幅に減らすことができて最高です⚙️。
  • Scaffolding: Railsにもあるやつです。簡単なコマンドで基本的なCRUD操作のためのコードを自動生成できます。先ほどのようにLiveViewを使用したSPAまで生成できちゃいます
  • hexdocsが整備されてて見やすい: パッケージのドキュメントが掲載されるページです。パッケージの公式ページで見やすいものってあまり無いですよね。特にpipとnpm
  • Phoenixのホットリロード: モダンなWebフレームワークでは標準だけど、やっぱり有り難い。さらに簡単にインタラクティブシェルを立ち上げられるので関数の動作確認するときなどとても便利!
  • 美しい文法:パイプや関数パターンマッチング、関数の呼び出し方など書いていて楽しいです🤗
    まだあまり詳しくないですが、学習意欲を掻き立てられますね!
  • Tailwind CSSがインストール済み: 皆さん好きですよね、デファクト化しつつあると思います。

Phoenixを使用した感想

LiveViewを初めとした革新的な新機能を導入しながら、細かい部分の使い心地も非常に良かったです。
こまれまでのフレームワークやエコシステムのいい点を取り込みつつ、煩わしさが取り除かれており面白くて、丁寧なフレームワークという印象でした。

Tips

github hero iconsをassetsに入れない方法

git init .するとやたら多くのファイルが作成されていてビックリするかもしれません。
主にheroiconsのCSVが原因です。CSVということもあり特にサイズが大きいくももないので、Githubにそのままpushしても構いません。

余分なファイルがコミットされるのが嫌な方(自分もそうでした)はassets/heroiconsを削除して、mix.exとmix.exsを書き換えることで、githubに余分なファイルをpushせずに済みます
他のelxirパッケージが保存されている /depsにheroiconsも保存されます。

rm -r ./assets/vendor/heroicons

assets/tailwind.config.js

-      let iconsDir = path.join(__dirname, "./vendor/heroicons/optimized")
+      let iconsDir = path.join(__dirname, "../deps/heroicons/optimized")
mix.exs
~~~~~~~
defp deps do
    [
      {:phoenix, "~> 1.7.10"},
      {:phoenix_ecto, "~> 4.4"},
      {:ecto_sql, "~> 3.10"},
      {:ecto_sqlite3, ">= 0.0.0"},
      {:phoenix_html, "~> 3.3"},
      {:phoenix_live_reload, "~> 1.2", only: :dev},
      {:phoenix_live_view, "~> 0.20.1"},
      {:heroicons,
       github: "tailwindlabs/heroicons",
       tag: "v2.0.18",
       app: false,
       compile: false,
       sparse: "optimized"},
       ~~~~~~~
    ]
  end
~~~~~~~

ビューにheroiconsを使用するコードを追加して動作を確認しましょう

lib/hello_web/controllers/page_html/home.html.heex
+    <.icon name="hero-star" class="w-16 h-16" />
mix deps.get
mix phx.servcer

最新のPhoenixの更新でオプションとして追加されたようです
開発コミュニティが活発そうでいいですね~🥰

参考文献

14
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
4