概述
到目前为止,我们只使用了一种类型的GraphQL 操作:查询。 这些是用于检索数据的只读操作。 要修改数据,我们需要使用另一种类型的 GraphQL 操作: 突变,这是写操作。
在本课中,我们将学习有关设计 突变 和突变响应的常见约定
突变
接下来是 MusicMatcher 项目中的下一个功能:将曲目添加到现有播放列表中。
让我们看一下启用此功能的相应 REST API 方法POST /playlists/{playlist_id}/tracks
.
从文档中,我们需要以下参数:
playlist_id
- 播放列表的 ID,作为string
(必需)position
- 一个integer
,从零开始的索引,我们想要插入曲目(们)的位置uris
- 一个以逗号分隔的string
,其中包含我们要添加的曲目的uri
值
然后,该方法将返回一个包含 snapshot_id
属性的对象,该属性表示播放列表在该时间点的状态。
好的,现在如何在 GraphQL 中启用此功能?
设计突变
让我们从我们的模式开始。
对于 突变 名称,我们建议以描述我们更新操作的特定动作的动词开头(例如添加、删除或创建),然后是突变作用于的数据。
对于 突变 的返回类型,我们可以返回 对象类型 突变作用于的对象。 但是,我们建议遵循一致的 Response
类型用于 突变 响应。
突变响应
我们需要考虑可能发生的任何部分错误并向客户端返回有用的信息。 我们建议在所有 突变 响应中添加三个常见的 字段:
code
:一个int
,它指的是响应的状态,类似于 HTTP 状态码。success
:一个bool
标志,指示 突变 负责的所有更新是否成功。message
:一个string
,用于显示有关 突变 结果的客户端信息。 如果突变仅部分成功,并且通用错误消息无法说明全部情况,这将特别有用。
然后,我们还将有一个 字段 用于我们正在突变的 对象类型(Playlist
,在本例中)。 在某些 突变 中,这可能是 多个 对象!
至于命名约定,返回类型通常以 Payload
或 Response
结尾。
AddItemsToPlaylistPayload
类型
遵循我们介绍的最佳实践,我们将为我们的 突变 命名为 AddItemsToPlaylist
。 让我们首先创建此 突变 的返回类型: AddItemsToPlaylistPayload
。
在 api/types
下,我们将创建一个名为 api/types/add_items_to_playlist_payload.py
的新文件。
在内部,我们将创建 AddItemsToPlaylistPayload
类,应用 @strawberry.type
装饰器。
import strawberry@strawberry.typeclass AddItemsToPlaylistPayload:...
然后,我们将为 code
、success
和 message
添加属性。
code: int = strawberry.field(description="Similar to HTTP status code, represents the status of the mutation.")success: bool = strawberry.field(description="Indicates whether the mutation was successful.")message: str = strawberry.field(description="Human-readable message for the UI.")
在本例中,我们正在突变的对象是 Playlist
类型,它是可为空的,因为突变可能会出错!
playlist: Playlist | None = strawberry.field(description="The playlist that contains the newly added items.")
我们还需要在文件顶部导入 Playlist
类型:
from .playlist import Playlist
一个新的入口点:Mutation
在 api
下,我们将创建一个名为 mutation.py
的新文件。 在此文件中,我们将定义一个名为 Mutation
的新类:
import strawberry@strawberry.typeclass Mutation:...
接下来,我们将为我们的 解析器 函数编写 AddItemsToPlaylist
字段。 它将返回 AddItemsToPlaylistPayload
类型。 我们也将为它添加一个描述。
我们将函数保持在 Pythonic snake_case
中,但请记住,Strawberry 会自动将它转换为模式中的 GraphQL camelCase
。
def add_items_to_playlist(self) -> AddItemsToPlaylistPayload:...
为了将其定义为一个 解析器,我们通常使用 @strawberry.field
装饰器,但这次我们将使用一个新函数: strawberry.mutation
。
该 strawberry.mutation
定义了用于 字段 的 mutation。它的工作方式与 strawberry.field
相同。我们可以将其用作装饰器,并提供 GraphQL 描述。
@strawberry.mutation(description="Add one or more items to a user's playlist.")def add_items_to_playlist(self) -> AddItemsToPlaylistPayload:...
我们现在将硬编码 解析器 的结果。小步走!我们将创建一个新的 AddItemsToPlaylistPayload
实例,将 200
传递给 code
,将 true
传递给 success
状态,传递一个成功的 message
和一个硬编码的 Playlist
对象。
return AddItemsToPlaylistPayload(code=200,success=True,message="Successfully added items to playlist.",playlist=Playlist(id="6Fl8d6KF0O4V5kFdbzalfW",name="Sweet Beats & Eats",description=None,),)
最后,我们将导入 AddItemsToPlaylistPayload
和 Playlist
类型,位于文件顶部:
from .types.add_items_to_playlist_payload import AddItemsToPlaylistPayloadfrom .types.playlist import Playlist
我们的 GraphQL 服务器 需要了解这个新的架构入口点。就像 Query
类型一样,我们需要在架构中设置 mutation 类型。
打开 api/schema.py
文件,并在顶部导入 Mutation
类。
from .mutation import Mutation
然后,我们将它传递给 strawberry.Schema
。
schema = strawberry.Schema(query=Query, mutation=Mutation)
保存所有这些更改并重启服务器。
探索时间!
是时候试试我们的 mutation 了!回到 Sandbox Explorer,我们将创建一个新的工作区选项卡。
在 Documentation 面板中,让我们导航回到架构的根目录。在 Query
旁边,我们可以看到 Mutation
类型。
让我们添加 addItemsToPlaylist
字段 以及其中的所有子字段。对于 playlist
子字段,现在选择 name
。
mutation AddItemsToPlaylist {addItemsToPlaylist {codemessagesuccessplaylist {name}}}
运行 mutation。
{"data": {"addItemsToPlaylist": {"code": "200","message": "Added items to playlist successfully","success": true,"playlist": {"name": "Sweet Beats & Eats"}}}}
就像 query 响应一样,我们的 mutation 响应也遵循与 mutation 相同的形状!
练习
AddItemsToPlaylistPayload
)中,为什么修改后的对象的返回类型(Playlist
)是可空的?关键要点
- Mutations 是写入 操作,用于修改数据。
- 命名 mutations 通常以一个描述动作的动词开头,例如 "add"、"delete" 或 "create"。
- 创建一致的 mutation 响应类型是一个常见的约定。
下一步
我们将学习 mutation 输入和返回真实数据的最佳实践。
分享您关于本课程的问题和评论
本课程目前处于
您需要一个 GitHub 帐户才能在下方发布。还没有? 改为在我们的 Odyssey 论坛中发布。