概述
到目前为止,我们只使用过一种类型的GraphQL 操作:查询。这些是用于检索数据的只读操作。为了修改数据,我们需要使用另一种类型的 GraphQL 操作: 突变,即写操作。
在本课中,我们将学习关于设计 突变 和突变响应的常见约定
突变
接下来我们将介绍 MusicMatcher 项目中的一个功能:将曲目添加到现有播放列表中。
让我们看看启用此功能的相应 REST API 方法POST /playlists/{playlist_id}/tracks
。
从文档中,我们需要以下参数:
playlist_id
- 播放列表的 ID,作为string
(必需)position
- 一个integer
,从零开始索引,表示我们要插入曲目(s)的位置uris
- 用逗号分隔的string
,包含我们想要添加的曲目的uri
值
然后该方法将返回一个包含 snapshot_id
属性的对象,该属性表示此时播放列表的状态。
好的,现在如何在 GraphQL中启用此功能?
设计突变
让我们从模式开始。
对于 突变 名称,我们建议使用一个动词开头,描述更新操作的具体行为(例如添加、删除或创建),然后加上突变所作用的数据。
对于突变的返回类型,我们可以返回突变所作用的 对象类型。但是,我们建议遵循一致的 Response
类型用于突变响应。
突变响应
我们需要考虑可能出现的任何部分错误,并向客户端返回有用的信息。我们建议向所有突变响应添加三个常见 字段:
code
:一个int
,用于引用响应的状态,类似于 HTTP 状态代码。success
:一个bool
标志,指示突变负责的所有更新是否成功。message
:一个string
,用于在客户端显示有关突变结果的信息。如果突变仅部分成功,而通用的错误消息无法说明全部情况,那么这将特别有用。
然后,我们还将有一个 字段 用于我们正在突变的 对象类型(在这种情况下为 Playlist
)。在某些突变中,这可能是 多个 对象!
至于命名约定,返回类型通常以单词 Payload
或 Response
结尾。
The AddItemsToPlaylistPayload
type
遵循我们所涵盖的最佳实践,我们将命名我们的 突变 为 AddItemsToPlaylist
。让我们首先为这个突变创建返回类型: AddItemsToPlaylistPayload
。
在 Types
下,我们将创建一个名为 AddItemsToPlaylistPayload
的新类文件。
namespace Odyssey.MusicMatcher;public class AddItemsToPlaylistPayload{}
然后,我们将添加 code
、success
和 message
的属性。
[GraphQLDescription("Similar to HTTP status code, represents the status of the mutation.")]public int Code { get; set; }[GraphQLDescription("Indicates whether the mutation was successful.")]public bool Success { get; set; }[GraphQLDescription("Human-readable message for the UI.")]public string Message { get; set; }
在这种情况下,我们正在突变的对象是 Playlist
类型,它是可为空的,因为突变中可能会出现问题!
[GraphQLDescription("The playlist that contains the newly added items.")]public Playlist? Playlist { get; set; }
最后,我们将添加构造函数。请记住使 playlist
参数可为空!突变可能会失败,我们不会收到播放列表对象。
public AddItemsToPlaylistPayload(int code, bool success, string message, Playlist? playlist){Code = code;Success = success;Message = message;if (playlist != null) {Playlist = playlist;}}
新的入口点:Mutation
在 Types
下,我们将创建一个名为 Mutation
的新类文件。
namespace Odyssey.MusicMatcher;public class Mutation{}
接下来,我们将为 解析器 函数编写我们的 AddItemsToPlaylist
字段。它将返回 AddItemsToPlaylistPayload
类型。我们还将为它添加一个描述。
[GraphQLDescription("Add one or more items to a user's playlist.")]public AddItemsToPlaylistPayload AddItemsToPlaylist(){}
然后,我们现在将对 解析器 的结果进行硬编码。循序渐进!我们将创建一个新的 AddItemsToPlaylistPayload
实例,为 code
传入 200
,为 success
状态传入 true
,一个成功的 message
和一个硬编码的 Playlist
对象。
return new AddItemsToPlaylistPayload(200,true,"Successfully added items to playlist.",new Playlist("6Fl8d6KF0O4V5kFdbzalfW", "Sweet Beats & Eats"));
我们GraphQL 服务器 需要知道这个新的模式入口点。与Query
类型类似,我们需要调用AddMutationType
在GraphQL 服务器 上,并将Mutation
类型传入。
builder.Services.AddGraphQLServer().AddQueryType<Query>().AddMutationType<Mutation>().RegisterService<SpotifyService>();
保存所有这些更改并重新启动服务器。
探索时间!
是时候让我们的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 通常以描述动作的动词开头,例如“添加”、“删除”或“创建”。
- 为mutation 响应创建一致的响应类型是一个普遍的约定。
接下来
我们将学习mutation 输入的最佳实践,并返回真实数据。
分享您对本课的疑问和评论
本课程目前处于
您需要一个 GitHub 帐户才能在下方发布。没有? 请在我们的 Odyssey 论坛上发布。