如何用Hot Chocolate和.NET 6开发GraphQL应用,实现Mutate数据更新功能?

2026-05-25 13:232阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计906个文字,预计阅读时间需要4分钟。

如何用Hot Chocolate和.NET 6开发GraphQL应用,实现Mutate数据更新功能?

系列导航:使用Hot Chocolate和.NET 6构建GraphQL应用文章索引需求:在上一篇文章中,我们演示了如何使用Hot Chocolate进行GraphQL的Mutate操作新增数据,本文我们将展示如何实现GraphQL中的数据更新。

系列导航

使用Hot Chocolate和.NET 6构建GraphQL应用文章索引

需求

在上一篇文章中,我们演示了如何使用Hot Chocolate进行GraphQL的Mutate新增数据,这篇文章我们将演示如何实现GraphQL中的数据更新任务。

思路

对数据的更新和新增数据的思路是一样的,都是使用Mutate机制进行更新。

实现

为了保持简单,我们先定义以下两个类型:

// 定义更新Post的参数 public record UpdatePostInput(Guid Id, string Title, string Author); // 定义新增Post的返回对象 public record UpdatePostPayload(Post Post);

新建Mutation.cs用来定义相关接口:

  • Mutation.cs

public async Task<UpdatePostPayload> UpdatePostAsync(UpdatePostInput input, [Service] IRepository<Post> repository) { var post = await repository.GetSingleAsync(p => p.Id == input.Id); if (post == null) { throw new ArgumentException($"no post with id: {input.Id} can be found!"); } post.Title = input.Title; post.Author = input.Author; return new UpdatePostPayload(await repository.UpdateAsync(post)); }

这样就实现了更新Post的需求,下面我们来验证一下。

验证

启动Api项目,先查询所有的Post数据:

如何用Hot Chocolate和.NET 6开发GraphQL应用,实现Mutate数据更新功能?

接下来对其中一条Post进行更新:

终端的日志输出如下:

[15:44:17 INF] Executing endpoint 'Hot Chocolate GraphQL Pipeline' [15:44:17 INF] Executed DbCommand (0ms) [Parameters=[@__input_Id_0='?' (DbType = Guid)], CommandType='Text', CommandTimeout='30'] SELECT "p"."Id", "p"."Abstraction", "p"."Author", "p"."Content", "p"."Created", "p"."CreatedBy", "p"."LastModified", "p"."LastModifiedBy", "p"."Link", "p"."PublishedAt", "p"."Title" FROM "Posts" AS "p" WHERE "p"."Id" = @__input_Id_0 LIMIT 1 [15:44:17 INF] Executed DbCommand (0ms) [Parameters=[@p10='?' (DbType = Guid), @p0='?' (Size = 66), @p1='?' (Size = 22), @p2='?' (Size = 30), @p3='?' (DbType = DateTime), @p4='?', @p5='?' (DbType = DateTime), @p6='?', @p7='?' (Size = 26), @p8='?' (DbType = DateTime), @p9='?' (Size = 59)], CommandType='Text', CommandTimeout='30'] UPDATE "Posts" SET "Abstraction" = @p0, "Author" = @p1, "Content" = @p2, "Created" = @p3, "CreatedBy" = @p4, "LastModified" = @p5, "LastModifiedBy" = @p6, "Link" = @p7, "PublishedAt" = @p8, "Title" = @p9 WHERE "Id" = @p10; SELECT changes(); [15:44:17 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline' [15:44:17 INF] Request finished HTTP/1.1 POST localhost:7194/graphql application/json 288 - 200 - application/json;+charset=utf-8 8.6091ms

再进行一次查询:

可以看到更新后的Post已经存储到数据库中了。

如果我们使用错误的Id去尝试更新数据,那么会得到这样的返回:

但是这样我们并不能看到具体的错误信息,即使我们在代码中已经明确throw了异常并填入了错误信息。接下来我们来解决这个问题。

扩展:自定义异常返回

为了让GraphQL的schema能够识别异常类型,最简单的方式是通过属性[Error(typeof())]来指定异常类型,我们当然可以穿入ArgumentException异常类型,为了演示如何自定义异常类型。我们新建一个异常类:

namespace PostGraphi.Api.GraphQL.Exceptions; public class PostNotFoundException : Exception { public PostNotFoundException(Guid id) : base($"no post with id: {id} can be found!") { } }

并修改Mutate方法属性和抛出异常的代码:

[Error(typeof(PostNotFoundException))] public async Task<UpdatePostPayload> UpdatePostAsync(UpdatePostInput input, [Service] IRepository<Post> repository) { var post = await repository.GetSingleAsync(p => p.Id == input.Id); if (post == null) { throw new PostNotFoundException(input.Id); } post.Title = input.Title; post.Author = input.Author; return new UpdatePostPayload(await repository.UpdateAsync(post)); }

最后还需要在引入依赖的时候进行配置,选择返回结果中包含具体的错误信息:

builder.Services .AddGraphQLServer() // ..... .ModifyRequestOptions(opt => opt.IncludeExceptionDetails = true);

再来测试一下:

在extension中我们看到了自定义的错误信息输出。

总结

在本文中我们实现了简单的更新Post操作,对于删除数据来说,思路并没有区别,所以我们下一篇文章将会直接介绍GraphQL中的另一大特性:Subscription。

本文共计906个文字,预计阅读时间需要4分钟。

如何用Hot Chocolate和.NET 6开发GraphQL应用,实现Mutate数据更新功能?

系列导航:使用Hot Chocolate和.NET 6构建GraphQL应用文章索引需求:在上一篇文章中,我们演示了如何使用Hot Chocolate进行GraphQL的Mutate操作新增数据,本文我们将展示如何实现GraphQL中的数据更新。

系列导航

使用Hot Chocolate和.NET 6构建GraphQL应用文章索引

需求

在上一篇文章中,我们演示了如何使用Hot Chocolate进行GraphQL的Mutate新增数据,这篇文章我们将演示如何实现GraphQL中的数据更新任务。

思路

对数据的更新和新增数据的思路是一样的,都是使用Mutate机制进行更新。

实现

为了保持简单,我们先定义以下两个类型:

// 定义更新Post的参数 public record UpdatePostInput(Guid Id, string Title, string Author); // 定义新增Post的返回对象 public record UpdatePostPayload(Post Post);

新建Mutation.cs用来定义相关接口:

  • Mutation.cs

public async Task<UpdatePostPayload> UpdatePostAsync(UpdatePostInput input, [Service] IRepository<Post> repository) { var post = await repository.GetSingleAsync(p => p.Id == input.Id); if (post == null) { throw new ArgumentException($"no post with id: {input.Id} can be found!"); } post.Title = input.Title; post.Author = input.Author; return new UpdatePostPayload(await repository.UpdateAsync(post)); }

这样就实现了更新Post的需求,下面我们来验证一下。

验证

启动Api项目,先查询所有的Post数据:

如何用Hot Chocolate和.NET 6开发GraphQL应用,实现Mutate数据更新功能?

接下来对其中一条Post进行更新:

终端的日志输出如下:

[15:44:17 INF] Executing endpoint 'Hot Chocolate GraphQL Pipeline' [15:44:17 INF] Executed DbCommand (0ms) [Parameters=[@__input_Id_0='?' (DbType = Guid)], CommandType='Text', CommandTimeout='30'] SELECT "p"."Id", "p"."Abstraction", "p"."Author", "p"."Content", "p"."Created", "p"."CreatedBy", "p"."LastModified", "p"."LastModifiedBy", "p"."Link", "p"."PublishedAt", "p"."Title" FROM "Posts" AS "p" WHERE "p"."Id" = @__input_Id_0 LIMIT 1 [15:44:17 INF] Executed DbCommand (0ms) [Parameters=[@p10='?' (DbType = Guid), @p0='?' (Size = 66), @p1='?' (Size = 22), @p2='?' (Size = 30), @p3='?' (DbType = DateTime), @p4='?', @p5='?' (DbType = DateTime), @p6='?', @p7='?' (Size = 26), @p8='?' (DbType = DateTime), @p9='?' (Size = 59)], CommandType='Text', CommandTimeout='30'] UPDATE "Posts" SET "Abstraction" = @p0, "Author" = @p1, "Content" = @p2, "Created" = @p3, "CreatedBy" = @p4, "LastModified" = @p5, "LastModifiedBy" = @p6, "Link" = @p7, "PublishedAt" = @p8, "Title" = @p9 WHERE "Id" = @p10; SELECT changes(); [15:44:17 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline' [15:44:17 INF] Request finished HTTP/1.1 POST localhost:7194/graphql application/json 288 - 200 - application/json;+charset=utf-8 8.6091ms

再进行一次查询:

可以看到更新后的Post已经存储到数据库中了。

如果我们使用错误的Id去尝试更新数据,那么会得到这样的返回:

但是这样我们并不能看到具体的错误信息,即使我们在代码中已经明确throw了异常并填入了错误信息。接下来我们来解决这个问题。

扩展:自定义异常返回

为了让GraphQL的schema能够识别异常类型,最简单的方式是通过属性[Error(typeof())]来指定异常类型,我们当然可以穿入ArgumentException异常类型,为了演示如何自定义异常类型。我们新建一个异常类:

namespace PostGraphi.Api.GraphQL.Exceptions; public class PostNotFoundException : Exception { public PostNotFoundException(Guid id) : base($"no post with id: {id} can be found!") { } }

并修改Mutate方法属性和抛出异常的代码:

[Error(typeof(PostNotFoundException))] public async Task<UpdatePostPayload> UpdatePostAsync(UpdatePostInput input, [Service] IRepository<Post> repository) { var post = await repository.GetSingleAsync(p => p.Id == input.Id); if (post == null) { throw new PostNotFoundException(input.Id); } post.Title = input.Title; post.Author = input.Author; return new UpdatePostPayload(await repository.UpdateAsync(post)); }

最后还需要在引入依赖的时候进行配置,选择返回结果中包含具体的错误信息:

builder.Services .AddGraphQLServer() // ..... .ModifyRequestOptions(opt => opt.IncludeExceptionDetails = true);

再来测试一下:

在extension中我们看到了自定义的错误信息输出。

总结

在本文中我们实现了简单的更新Post操作,对于删除数据来说,思路并没有区别,所以我们下一篇文章将会直接介绍GraphQL中的另一大特性:Subscription。