Open4

Replit上のPhoenixLiveViewでHTTP APIにアクセスするメモ

MzRyuKaMzRyuKa

Replitで、PhoenixLiveViewでHTTP APIを呼び出して、画像を表示する対応。

呼び出すAPIには、これを利用。

https://dog.ceo/dog-api/documentation/random

また、HTTPレスポンスには、Reqを利用することにしてみた。

https://hexdocs.pm/req/readme.html

Reqは、こちらの記事を参考にして。
→HTTPoisonとJasonの両方を兼ねてそうなんで。

ReplにReqをインストールする。

テンプレート「Phoeinx」で作られるプロジェクトではReqは入っていないので、mix.exsdefp deps do ~ endReqを追加後にConsole欄かShell欄でmix deps.getを実行する。

mix.exsreqを追加

修正イメージはこちら。

mix.exs
  defp deps do
    [
      {:phoenix, "~> 1.6.6"},
      {:phoenix_ecto, "~> 4.4"},
      {:ecto_sql, "~> 3.6"},
      {:ecto_sqlite3, ">= 0.0.0"},
      {:phoenix_html, "~> 3.0"},
      {:phoenix_live_reload, "~> 1.2", only: :dev},
      {:phoenix_live_view, "~> 0.17.5"},
〜(中略)〜
      {:jason, "~> 1.2"},
      {:req, "~> 0.3"},  # ←これを追記
      {:plug_cowboy, "~> 2.5"}
    ]
  end

修正後に、mix deps.getを実行する

> mix deps.get

Resolving Hex dependencies...
Dependency resolution completed:
Unchanged:
  castore 0.1.14
  connection 1.1.0
  cowboy 2.9.0
  cowboy_telemetry 0.4.0
  cowlib 2.11.0
  db_connection 2.4.1
  decimal 2.0.0
  ecto 3.7.1
  ecto_sql 3.7.2
  ecto_sqlite3 0.7.3
  elixir_make 0.6.3
  esbuild 0.4.0
  exqlite 0.9.1
  file_system 0.2.10
  floki 0.32.0
  gettext 0.19.0
  html_entities 0.5.2
  jason 1.3.0
  mime 2.0.2
  phoenix 1.6.6
  phoenix_ecto 4.4.0
  phoenix_html 3.2.0
  phoenix_live_dashboard 0.6.2
  phoenix_live_reload 1.3.3
  phoenix_live_view 0.17.6
  phoenix_pubsub 2.0.0
  phoenix_view 1.1.0
  plug 1.12.1
  plug_cowboy 2.5.2
  plug_crypto 1.2.2
  ranch 1.8.0
  swoosh 1.6.0
  telemetry 1.0.0
  telemetry_metrics 0.6.1
  telemetry_poller 1.0.0
New:
  finch 0.16.0
  hpax 0.1.2
  mint 1.5.1
  nimble_options 1.0.2
  nimble_pool 1.0.0
  req 0.3.6
* Getting req (Hex package)
* Getting finch (Hex package)
* Getting mint (Hex package)
* Getting nimble_options (Hex package)
* Getting nimble_pool (Hex package)
* Getting hpax (Hex package)
MzRyuKaMzRyuKa

以下の修正とファイル追加を実施。

追加

  • パス「lib/phoenix_app_web/live/dog_image_live」を追加
    • lib/phoenix_app_web下に、「live」フォルダ、「dog_image_live」フォルダを作成
  • ファイル「lib/phoenix_app_web/live/dog_image_live/index.ex」を作成。
  • ファイル「lib/phoenix_app_web/live/dog_image_live/index.html.heex」を作成
lib/phoenix_app_web/live/dog_image_live/index.ex
defmodule PhoenixAppWeb.DogImageLive.Index do
  use PhoenixAppWeb, :live_view

  @impl true
  def mount(_params, _session, socket) do
    {:ok, assign(socket, dog_image_url: nil)}
  end

  @impl true
  def handle_params(params, _url, socket) do
    {:noreply, apply_action(socket, socket.assigns.live_action, params)}
  end

  defp apply_action(socket, :index, _params) do
    socket
    |> assign(:dog_image_url, nil)
  end

  @impl true
  def handle_event("submit", %{}, socket) do
    send( self(), {:get_doc} )
    {:noreply, assign(socket, dog_image_url: nil)}
  end

  @impl true
  def handle_info(  {:get_doc}, socket) do
    {:noreply, assign(socket, dog_image_url: dog_image_url())} 
  end

  @impl true
  defp dog_image_url do
    url = "https://dog.ceo/api/breeds/image/random"
    Req.get!(url).body["message"]
  end
end
lib/phoenix_app_web/live/dog_image_live/index.html.heex
<h1>Dog Image</h1>

<form phx-submit="submit">
<input type="submit" name="Fetch" onclick="blur()" />
<p>ボタンクリックで画像が出てきます:</p>
</form>

<%= if @dog_image_url do %>
<p> <%= @dog_image_url %> </p>
<p> <img src={"#{@dog_image_url}"} > </p>
<% end %>

修正

  • lib/phoenix_app_web/templates/page/index.html.heex
    • 新kに追加した「Dog Image」へのリンクをTOPページに追記
  • lib/phoenix_app_web/router.ex
    • 新規追加した「Dog Image」へのパスを追記
lib/phoenix_app_web/templates/page/index.html.heex
〜省略〜
      <li>
        <a href="/dogimage">Dog Image</a>
      </li>
      <li>
        <a href="https://hexdocs.pm/phoenix/overview.html">Guides &amp; Docs</a>
〜省略〜
lib/phoenix_app_web/router.ex
〜省略〜
  scope "/", PhoenixAppWeb do
    pipe_through :browser

    live "/dogimage", DogImageLive.Index, :index   #←これを追記

    get "/", PageController, :index
  end
〜省略〜
MzRyuKaMzRyuKa

実行結果:

リンクができたのでクリック

作成した画面へ遷移

ボタンをクリックしてみる。
犬の画像が表示された。

もう一度ボタンをクリックしてみる。
再び別の犬の画像が表示された。