LoginSignup
5
1

More than 1 year has passed since last update.

LiveViewをクライアントにしてGraphQLによる連携を実装する

Posted at

東京だけど fukuoka.ex の YOSUKENAKAO.me です。

普段は合同会社The Waggleで「教育」に関わるサービス作りのお仕事と学習教材の開発や研修講座の企画開発をしています。

現在、企業研修講師を募集しています。また、これから講師もキャリアとしてデビューしたい方も育成プランがありますので興味ある方はご連絡ください。

また、ARグラスのアプリ開発も行っていますので、Unityを使ってAR開発に興味ある方も募集してます。

記事構成

この記事は関連記事と併せて4部作で考えています。

  1. GraphCMSを利用してヘッドレスCMSを構築しPhoenix LiveViewでGraphQL-Crientを実装しよう。ここではNuronを使った簡単なGraphQL-Crientの実装を試します。ちなみにGraphCMSの使い方については、要望多ければ別途記事にしますので、是非知りたい方はこちらの記事にアクションください。また、このチュートリアルではGraphCMSを利用しましたが、GraphQL Server機能を持っていれば何でも構いません。(本記事)

  2. GraphQL ServerをPhoenixで構築しよう!(前編) Elixirアドベントカレンダー 12/8 投稿予定

  3. GraphQL ServerをPhoenixで構築しよう!(後編) Elixirアドベントカレンダー 12/15 投稿予定

  4. GraphQL Crientの変更Subscriptionsを実装しよう。 1で作成したGraphQLクライアントは、Subscriptionsがサポートされてない為、せっかくLiveViewを実装したのに、その恩恵があまり受けられないものとなってました。そこで、このシリーズの第4段では、その課題を解決する実装を模索したいと思います。  Elixirアドベントカレンダー 12/22 投稿予定

LiveViewをクライアントにしたGraphQLによる連携実装の概要

このチュートリアルは、以前書いたこちらの記事のリニューアル版です。が、当時はReactをフロントにバックエンドとしてGraphQLサーバーをPhoenixフレームワークを使って構築する方法をあげていました。しかし、最近ではLiveViewが充実してきたこともあり、クライアント側をLiveView(Phoenix)バックエンド側をGraphQL(Phoenix)の構成にしたものにします。

1.GraphCMSのアカウント登録

下記のサイトへアクセスしてください。
アカウントを作成してください。特に難しい事しないので割愛します。
https://graphcms.com/

DEMO版のBlogを選びます。

アカウントを作成してログインした後、Add a new projectより 真ん中の サンプル Blog を選択します。
PS. Phoenixを学んで、何作ろうかな?DBの設計とか知らんしな。って方はこのサンプルでどのようにDB設計されてるか見れるのでおすすめです。

スクリーンショット 2022-10-20 8.09.23.png

リージョンを選択

ProjectのDetailsは特に変更しなくて大丈夫ですが、Regionについては、Japan(Tokyo)を選択してください。

スクリーンショット 2022-10-20 8.10.01.png

完成まで待つ

作成までしばらく時間がかかるので、のんびり待ちます。完了すると下記のような画面が見れます。

スクリーンショット 2022-10-20 8.39.38.png

ここまで準備できたら、一旦LiveViewのフロント側を準備していきます。

2. LiveViewのフロント実装

まずは、DBが不要なので、 --no-ecto オプションをつけて LiveViewのプロジェクトを生成します。今回はfetchという名前で作成してみました。

mix phx.new fetch --no-ecto --live

Graphql クライアントのインストールをします。
今回はシンプルに使いやすそうなGraphQL Crientの機能を追加できる neuron を使用します。

mix.exs
defp deps do
 [
   # existing dependencies
    {:neuron, "~> 5.0.0"}
 ]
end
mix deps.get

以下の依存関係が追加されます。

New:
  certifi 2.9.0
  hackney 1.18.1
  httpoison 1.8.2
  idna 6.1.1
  metrics 1.0.1
  mimerl 1.2.0
  neuron 5.0.0
  parse_trans 3.3.1
  ssl_verify_fun 1.1.6
  unicode_util_compat 0.7.0

GraphCMSとの接続

Neuronを使ってGraphCMSと接続してみましょう。
まずは、GraphCMSのエンドポイントとトークンをコピーし、それぞれ環境変数にセットしておきます。

Endpointの設定

スクリーンショット 2022-11-05 12.21.59.png

Content APIをコピーして、環境変数にセットしておきます。


export EX_GRAPHCMS_ENDPOINT="Content API(Endpoint)"

Tokenの設定

スクリーンショット 2022-11-05 12.23.15.png

export EX_GRAPHCMS_TOKEN="HYGRAPH_TOKENのValueをコピーした値"

それぞれ、環境変数に設定したら、Neuronのコンフィグに設定します。

iex> Neuron.Config.set(url: System.get_env("EX_GRAPHCMS_ENDPOINT"))
:ok
iex> Neuron.Config.set(headers: ["Authorization": System.get_env("EX_GRAPHCMS_TOKEN")])
:ok

これで、GraphQLを取得する為の準びが完了したので、早速試して行きたいと思います。

GraphQLでクエリを叩いてみる

Neuron.query("""
{
# ここにgraphQL のクエリを書く
}
""")

成功すると、status_code: 200 と共に、"data" =>以下にデータを取得する事ができます。

iex(4)>  Neuron.query("""
...(4)>     {
...(4)>       posts{
...(4)>         title
...(4)>         slug
...(4)>         id
...(4)>       }
...(4)>     }
...(4)>     """)
{:ok,
 %Neuron.Response{
   body: %{
     "data" => %{
       "posts" => [
         %{
           "id" => "ホニャララ",
           "slug" => "ホニャララスラグ",
           "title" => "Technical SEO with Hygraph"
         },
# ~ 省略 ~ 
   headers: [
     {"Date", "Sat, 05 Nov 2022 04:40:01 GMT"},
     {"Content-Type", "application/json"},
     {"Transfer-Encoding", "chunked"},
     {"Connection", "keep-alive"},
     {"Server", "cloudflare"}
# ~ 省略 ~ 
   ],
   status_code: 200
 }}

とりあえず、これでNeronを利用してGraphCMSからGraphQLを利用してデータを取得する事ができたので、早速LiveViewに反映させて行きたいと思います。

lib/fetch/blog.ex
defmodule Fetch.Blog do
  def get_blogs() do
    Neuron.query("""
    {
      posts{
        title
        slug
        id
      }
    }
    """)
  end
end

LiveViewでデータを取得して表示する処理を記載します。

lib/fetch_web/live/blogs_live.ex
defmodule FetchWeb.BlogsLive do
  use FetchWeb, :live_view
  alias Fetch.Blog
  def mount(_params, _session, socket) do
    {:ok, blogs} = Blog.get_blogs()
    blogs = get_in(blogs.body["data"], ["posts"])
    socket = assign(socket, blogs: blogs)
    {:ok, socket}
  end

  def render(assigns) do
    ~L"""
    <%= for blog <- @blogs do %>
      Title: <%= blog["title"] %> </br>
      slug:  <%= blog["slug"] %></br>
      id:  <%= blog["id"] %>
      <hr>
    <% end %>
    """
  end
end

routerにliveViewへのルートを追記

lib/fetch_web/router.ex
# ~ 省略 ~
 scope "/", FetchWeb do
    pipe_through :browser

    live "/blogs", BlogsLive #<- こちらを追記
  end

これで完成!と言いたい所ですが、このままだと、Neuron.configの設定を反映する箇所が抜けています。そこで、最後にアプリケーションファイルにNeuronのコンフィグ設定を追記します。

lib/fetch/apprication.ex
defmodule Fetch.Application do
  @moduledoc false
  use Application

  @impl true
  def start(_type, _args) do
    children = [
        # ~ 省略 ~
    ]

        # ~ 省略 ~

    Neuron.Config.set(url: System.get_env("EX_GRAPHCMS_ENDPOINT")) #<- こちらを追記
    Neuron.Config.set(headers: ["Authorization": System.get_env("EX_GRAPHCMS_TOKEN")]) #<- こちらを追記

    Supervisor.start_link(children, opts)
  end
        # ~ 省略 ~
end

最後にちゃんと取得できてるか確認しましょう。

mix phx.server

無事に取得できてるようですね。

スクリーンショット 2022-11-05 14.56.10.png

最後に

いかがだったでしょうか、本当は、この後 WebSocketを使って、データ書き換えを即時反映させたいと思ったのですが、Neuronのライブラリでは、GraphQLのSubscriptionsがサポートされておらず、Issueに上がってるものの、時間なくていつ取り込まれるかわかりません!とコメントされていたので、この後の続くシリーズにて、最終的には別のライブラリに変更して対応したいと考えてます。

という事で、Elixir Advent Calendar 2022 で続きを書いて行きたいと思います!
よければ、いいね。よろしくお願いします。励みになります。

5
1
0

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
5
1