概述
解析器负责为我们模式中的特定字段返回数据。到目前为止,我们已经返回了硬编码的播放列表数据,但现在是时候用对我们 REST API 的调用来替换它了。
在本课中,我们将
- 了解如何从数据源访问解析器函数
- 使用
HttpClient
向端点发出 REST API 调用 - 将 HTTP 响应类型转换为我们的解析器和模式所期望的类型
解析器
到目前为止,我们编写了不需要任何参数的解析器函数。例如,Query.Hello
解析器立即返回了字符串值“Hello World”。
我们还有播放列表的解析器属性Id
、Name
和Description
,其中每个字段的get
访问器充当解析器函数。
但解析器可以做更多的事情!解析器可以接受以下参数:
- 的值GraphQL 参数。GraphQL 参数用于标识、过滤或转换数据。我们将在下一课中介绍这一点。
- 该父级值。我们也将在后面的课程中介绍这一点。
HttpContext
。发送到服务器的 HTTP 请求所涉及的上下文。- 数据源(或服务)。我们使用依赖注入注册到服务器的服务。
在本课中,我们将重点介绍数据源参数。
访问数据源
在上一课中,我们将SpotifyService
注册到我们的GraphQL 服务器,以便我们可以在解析器函数中访问它。
在Query.cs
中,让我们通过将SpotifyService
添加为FeaturedPlaylists
函数中的参数来使用SpotifyService
。
public List<Playlist> FeaturedPlaylists(SpotifyService spotifyService)
确保我们也在顶部导入了SpotifyWeb
包,SpotifyService
位于其中(否则,您将看到错误!)。
using SpotifyWeb;
就这样!我们可以在解析器函数体中的任何地方使用spotifyService
实例。
在上一课中,我们多做了一步,在我们的GraphQL 服务器中使用了RegisterService<SpotifyService>
,这是可选的。如果我们没有这样做,我们的解析器函数将改为如下所示:
public List<Playlist> FeaturedPlaylists([Service] SpotifyService spotifyService)
我们需要包含[Service]
属性以及SpotifyService
才能访问它!省略它不是更简洁吗?我们认为是的!
GetFeaturedPlaylists
提示:利用您的代码编辑器的 IntelliSense 功能来了解spotifyService
中有哪些可用方法!
现在我们可以访问spotifyService
了,我们可以进行第一次 HTTP 调用并存储响应。
var response = spotifyService.GetFeaturedPlaylistsAsync();
该GetFeaturedPlaylistsAsync
方法映射到我们之前探索的GET /browse/featured-playlists
端点。
此方法是异步的,因此我们将await
结果并将该函数标记为async
。对于异步函数,返回类型也需要是Task<T>
类型。
public async Task<List<Playlist>> FeaturedPlaylists(SpotifyService spotifyService){var response = await spotifyService.GetFeaturedPlaylistsAsync();// return new List<Playlist>{...};}
将鼠标悬停在response
变量上,我们可以看到它的类型是SpotifyWeb.FeaturedPlaylists
。这就是我们之前看到的响应类型(在 REST API 文档中),具有message
和playlists
这两个顶级属性。它不是此解析器函数应返回的类型。相反,我们必须访问response.Playlists.Items
。
var items = response.Playlists.Items;
现在items
变量是一个PlaylistSimplified
类型集合(此类型是在SpotifyWeb
中定义的)。它不完全是一个Playlist
类型,但它确实包含我们需要将其转换为Playlist
类型的属性!
要将PlaylistSimplified
类型转换为Playlist
类型,我们将创建一个新的构造函数,该构造函数位于Playlist
类中。
打开Playlist.cs
并创建一个新的构造函数,该构造函数接受一个PlaylistSimplified
对象,并使用该对象的属性设置每个Playlist
属性。
public Playlist(PlaylistSimplified obj){Id = obj.Id;Name = obj.Name;Description = obj.Description;}
不要忘记在顶部导入SpotifyWeb
命名空间,因为PlaylistSimplified
来自该包(最好让您的代码编辑器为您自动导入!)。
using SpotifyWeb;
现在我们可以在Query.FeaturedPlaylists
解析器中使用此构造函数了。我们将使用Select
函数遍历items
集合中的每个PlaylistSimplified
对象,并返回一个新的Playlist
对象。
var playlists = items.Select(item => new Playlist(item));
最后,我们需要使用 ToList()
将集合转换为列表,以匹配 List<Playlist>
类型,这是 解析器 要返回的类型!
return playlists.ToList();
完美!请随意将所有内容合并到一行干净的代码中。
return response.Playlists.Items.Select(item => new Playlist(item)).ToList();
我们现在可以删除之前硬编码的 Playlist
对象了。
- return new List<Playlist>- {- new Playlist("1", "GraphQL Groovin'"),- new Playlist("2", "Graph Explorer Jams"),- new Playlist("3", "Interpretive GraphQL Dance")- };
探索时间!
很激动想看看这些代码都做了些什么吧?确保所有文件都已保存,并且服务器正在运行最新更改。
让我们跳到Sandbox Explorer 并运行相同用于精选播放列表的 查询。
query FeaturedPlaylists {featuredPlaylists {idnamedescription}}
看,我们从 REST API 数据源中获取了精选的播放列表 ✨
与 REST 方式比较
让我们戴上产品应用程序开发人员的帽子,花点时间比较一下,如果我们使用 REST 而不是 GraphQL,这个功能会是什么样子。
如果我们使用 REST,应用程序逻辑将包括
- 对
/browse/featured-playlists
端点进行 HTTPGET
调用 - 深入响应 JSON 的
playlists.items
属性 - 仅检索
id
、name
和description
属性,丢弃 所有其他 响应。
还有很多没有被使用的响应!如果客户端应用程序的网络速度很慢或者数据量很少,这个大的响应会带来一定的成本。
使用 GraphQL,我们获得了简短、简洁、易读的来自客户端的 操作,以他们指定的完全相同的形状返回,不多不少!
所有提取数据和过滤哪些 字段 的逻辑都在 GraphQL 服务器端完成。
注意:如您所见,REST 和 GraphQL 可以协同工作!在此视频中了解有关此动态的更多信息"GraphQL and REST: true BFFs - Dan Boerner / API World".
练习
关键要点
- 解析器 函数可以接受参数,例如 GraphQL 参数 的值、
parent
值、HttpContext 和 数据源。 - 通过使用 GraphQL API 而不是 REST API,我们避免了处理大量响应数据。
下一步
激动人心的进展!但您可能在想——没有歌曲的播放列表有什么意义?在接下来的几节课中,我们将解决下一个功能:播放列表的曲目。
分享您对本课的疑问和评论
本课程目前处于
您需要一个 GitHub 帐户才能在下面发布。还没有吗? 请在 Odyssey 论坛上发布。