系列導航
使用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資料:

接下來對其中一條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 https://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,
本文來自博客園,作者:CODE4NOTHING,轉載請注明原文鏈接:https://www.cnblogs.com/code4nothing/p/graphql-net6-9.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/433145.html
標籤:.NET技术
