10. 解析器和数据源
5m

概述

负责为我们模式中的特定返回数据。到目前为止,我们一直返回硬编码的播放列表数据,但现在是时候用对 REST API 的调用来替换它了。

在本课中,我们将

  • 学习如何访问context 对象在我们的
  • 使用生成的 Spotify Client 来对端点进行 REST API 调用
  • 将 HTTP 响应类型转换为我们的和模式所期望的类型

解析器参数

一个可以接受以下参数:

  • self: 代表类本身。它也代表特定parent(我们将在本课程的后面部分介绍)。
  • 对于参数的值。 用于识别、过滤或转换数据。我们将在本课程的后面部分介绍。
  • info. 关于当前的信息,例如名称、路径等。它还包含context 对象,可用于数据库连接、身份验证信息等,正如我们将在本课中看到的那样,我们的 Spotify 客户端!

在本课中,我们将使用info 参数。

从解析器访问 spotify_client

打开api/query.py 文件并找到featured_playlists 函数。

为了访问spotify_client 对象在context 中,我们将向 函数添加一个新参数,称为info,类型为strawberry.Info

api/query.py
def featured_playlists(self, info: strawberry.Info) -> list[Playlist]:

当一个有一个类型为strawberry.Info 的参数时,Strawberry 将自动将info 对象传递给

info 对象中,我们可以提取spotify_client 并将其分配给一个

api/query.py
spotify_client = info.context["spotify_client"]

发送精选播放列表的请求

现在我们有了客户端,我们可以使用它向 Spotify REST API 发出请求。我们将使用我们生成的客户端中的get_featured_playlists 模块,所以让我们在顶部导入它。

api/query.py
from mock_spotify_rest_api_client.api.playlists import get_featured_playlists

此模块中有一些函数,但我们将专门使用asyncio 函数。也有一个同步版本可用,但我们建议使用异步版本以避免在每次向 Spotify API 发出请求时阻塞服务器。

我们需要更新我们的,使其也成为异步的。

- def featured_playlists(self, info: strawberry.Info) -> list[Playlist]:
+ async def featured_playlists(self, info: strawberry.Info) -> list[Playlist]:

现在我们已经准备好获取精选播放列表了!

featured_playlists 中,我们将调用get_featured_playlists.asyncio 函数,将spotify_client 传递到client 中的

我们将await 该调用并将结果存储在一个名为data中。

api/query.py
data = await get_featured_playlists.asyncio(client=spotify_client)

返回正确的数据类型

将鼠标悬停在data 上,我们可以看到它的类型为SpotifyObjectFeaturedPlaylists。这是我们之前看到的(在 REST API 文档中)的具有顶层属性messageplaylists 的响应类型。它不是 函数应该返回的内容;我们希望返回一个Playlist 类型列表。

要获得我们实际需要的数据,我们必须深入到data.playlist.items 中。

api/query.py
items = data.playlists.items

现在将鼠标悬停在items 上,我们可以看到它是一个SpotifyObjectPlaylistSimplified 类型列表。它不完全是一个Playlist 类型,但它确实包含我们需要将它转换为Playlist 类型的属性!

让我们生成一个列表,遍历items 列表中的每个playlist 并根据我们需要的idnamedescription)创建Playlist 实例。

api/query.py
playlists = [
Playlist(
id=strawberry.ID(playlist.id),
name=playlist.name,
description=playlist.description,
)
for playlist in items
]

最后,我们可以返回playlists

api/query.py
return playlists

完美!可以将所有内容整合到一个简洁的语句中(无需额外的 )。

api/query.py
return [
Playlist(
id=strawberry.ID(playlist.id),
name=playlist.name,
description=playlist.description,
)
for playlist in data.playlists.items
]

现在我们可以移除之前硬编码的 Playlist 对象了。

api/query.py
- return [
- Playlist(id="1", name="GraphQL Groovin'", description=None),
- Playlist(id="2", name="Graph Explorer Jams", description=None),
- Playlist(id="3", name="Interpretive GraphQL Dance", description=None),
- ]

探索时间!

激动地想知道这些代码都做了什么吗?确保所有文件都已保存,并且服务器正在运行最新更改。

让我们跳到沙盒浏览器 并运行相同的 获取特色播放列表。

GraphQL 操作
query FeaturedPlaylists {
featuredPlaylists {
id
name
description
}
}

看!我们从 REST API 数据源获得了特色播放列表

https://127.0.0.1:8000

Response data

与 REST 方法比较

让我们戴上产品应用程序开发者的帽子,思考一下如果我们使用 REST 而不是 ,这个功能会是什么样。

如果我们使用 REST,应用程序逻辑将包括

  • /browse/featured-playlists 端点进行 HTTP GET 调用
  • 深入响应 JSON 的 playlists.items 属性
  • 仅检索 idnamedescription 属性,丢弃 所有其他 响应。

还有很多未使用的响应内容!如果客户端应用程序网络速度慢或数据量不多,这种大型响应会带来成本。

使用 ,我们拥有简洁、干净、可读的 ,它来自客户端,并以他们指定的精确形状返回,不多不少!

端完成所有提取数据和过滤所需 的逻辑。

注意:正如您所见,REST 和 可以协同工作!您可以通过观看此视频了解更多信息 "GraphQL 和 REST:真正的 BFF - Dan Boerner / API 世界".

关键要点

  • 函数可以接受参数,例如 info
  • 通过使用 API 而不是 REST API,我们可以避免处理大型响应数据。

接下来

令人兴奋的进展!在下一课中,我们将学习 以及如何在 函数中访问它们。

上一页

分享您关于本课的问题和评论

本课程目前处于

测试版
.您的反馈将帮助我们改进!如果您遇到问题或困惑,请告诉我们,我们将帮助您。所有评论都是公开的,必须遵守 Apollo 行为准则。请注意,已解决或已处理的评论可能会被删除。

您需要一个 GitHub 帐户才能在下面发布。还没有? 请改在我们的 Odyssey 论坛中发布。