使用LiveView作为客户端实现与GraphQL的集成
我在东京,但是我是 fukuoka.ex 的 YOSUKENAKAO.me。
我平常在合同公司The Waggle从事与“教育”有关的服务创建工作、学习教材开发以及培训课程的企划开发。
我们现在正在招聘企业培训讲师。同时,对于希望将讲师作为职业起步的人,我们也有培养计划。如果您有兴趣,请与我们联系。
此外,我们也正在进行AR眼镜应用开发,并寻求对使用Unity进行AR开发感兴趣的人才。
新闻结构
本文与相关文章一同构成了一个四部作品。
-
- 使用GraphCMS建立Headless CMS,并在Phoenix LiveView上实现GraphQL客户端。在这里,我们将尝试使用Nuron进行简单的GraphQL客户端实现。另外,如果有人想了解有关GraphCMS的用法,请务必在此文章中行动,如果有需求多的话,我们将另行发布一篇文章介绍。此外,在本教程中我们使用了GraphCMS,但只要有GraphQL服务器功能,使用其他平台也是可以的。(这篇文章)。
让我们在Phoenix上建立GraphQL服务器!(上篇)将于12月8日发布于Elixir Advent Calendar。
让我们在Phoenix上建立GraphQL服务器!(下篇)将于12月15日发布于Elixir Advent Calendar。
让我们实现GraphQL客户端的订阅功能。由于在第一部分创建的GraphQL客户端不支持订阅功能,所以尽管我们已经实现了LiveView,但却不能充分享受其好处。因此,在本系列的第四部分中,我们将探索解决这个问题的实现方法。将于12月22日发布于Elixir Advent Calendar。
使用LiveView作为客户端实现GraphQL的概述。
这个教程是我之前写的那篇文章的更新版。当时,我介绍了如何使用React作为前端,Phoenix框架作为后端,搭建GraphQL服务器的方法。然而,最近由于LiveView的发展,我决定将客户端改为LiveView(Phoenix),后端改为GraphQL(Phoenix)的配置方式。
1. 注册GraphCMS的账户
请访问以下网站链接。
请创建一个账号。不需要做任何特别困难的事情,就简单忽略掉吧。
https://graphcms.com/
我会选择Demo版的博客。
在创建和登录账户后,从”Add a new project”选项中选择中间的”Sample Blog”。
PS. 如果你正在学习Phoenix,想知道该做什么?又不了解数据库设计之类的,那么推荐你通过查看这个示例来了解数据库设计是如何进行的。
选择区域
请不必特别更改项目的细节,但需要在地区中选择日本(东京)。
请等待直到完成。
由于制作需要一段时间,所以我会悠闲地等待。完成后,您将能够看到下面这样的画面。
一旦准备好这一步,我们将开始准备LiveView的前端部分。
2. LiveView 的前端实现
首先,由于不需要数据库,我们可以使用 –no-ecto 选项来创建 LiveView 项目。这次我尝试以 fetch 作为项目名称进行创建。
mix phx.new fetch --no-ecto --live
我們將安裝GraphQL客戶端。
這次我們將使用一個看起來簡單易用的GraphQL客戶端neuron,並添加其功能。
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的连接 (Yǔ GraphCMS de
让我们使用neuron来连接GraphCMS。首先,复制GraphCMS的端点和令牌,并将它们分别设置为环境变量。
设置Endpoint
将Content API复制并设置为环境变量。
export EX_GRAPHCMS_ENDPOINT="Content API(Endpoint)"
设定Token
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 のクエリを書く
}
""")
成功时,可以获取数据,状态码为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上。
defmodule Fetch.Blog do
def get_blogs() do
Neuron.query("""
{
posts{
title
slug
id
}
}
""")
end
end
我会在LiveView中编写代码来获取并显示数据。
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
在路由器中添加到实时视图的路由
# ~ 省略 ~
scope "/", FetchWeb do
pipe_through :browser
live "/blogs", BlogsLive #<- こちらを追記
end
这里应该是完成了!但是,这样下去的话,会漏掉对Neuron.config的设置反映的部分。所以,我们在最后会在应用程序文件中添加Neuron的配置设置。
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
听起来你已经顺利取得了呢。
最后
请问您觉得如何?事实上,我本来想在之后使用WebSocket来实时反映数据的更改,但是Neuron的库不支持GraphQL的Subscriptions。虽然这个问题已经被提出来了,但由于时间关系,我不知道它何时会被纳入!因此,我计划在接下来的系列中最终改用另一个库进行处理。
希望在2022年的Elixir圣诞日历中继续写下去!如果可以的话,请点个赞。谢谢你的支持,这对我来说是一种鼓励。