飞雪团队

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 12813|回复: 0

使用Hot Chocolate和.NET 6构建GraphQL应用(8) —— 实现Mutate添加数据 ...

[复制链接]

8044

主题

8132

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26462
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式

) k: e! O0 o2 J, ~, M; f<h2 id="系列导航">系列导航</h2>
+ a! {+ M2 W# P# L6 E& O<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>+ i$ |2 t" |! U" \
<h2 id="需求">需求</h2>: Q2 ]/ v7 O: z8 B
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>; @5 M+ U7 y" i3 @; {4 Q
<h2 id="思路">思路</h2>
* B; k9 [; Y3 F: Z<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p># [/ h. a9 D0 t: X4 n; p
<h2 id="实现">实现</h2>8 {: j/ v* B# t+ d0 {3 _
<p>为了保持简单,我们先定义以下两个类型:</p>
' C. H0 `/ _# ]<pre><code class="language-c#">// 定义新增Post的参数$ L1 B, k, E+ h1 K/ p: j
public record AddPostInput(string Title, string Author);
# J; R5 K; x9 k1 ^, Q+ N. t9 N# n( n4 y
5 D9 e% G; d1 b4 I7 b& m. k) A; ~// 定义新增Post的返回对象
2 @( K/ i& b+ m+ h6 Wpublic record AddPostPayload(Post Post);
* O4 }  f( P- \0 O# G</code></pre>
. x: {- a: ?. P<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>3 C- \2 L0 m; Z. R7 F1 I0 `
<ul>' e/ W' t; W% N
<li><code>Mutation.cs</code></li>
2 X# f# v3 \7 b8 R( A</ul>
5 r. b$ E; k8 j$ F! E% T<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
$ x! d9 R, l# C+ \9 d+ f3 ?9 i" u+ c* F5 j* J, n
public class Mutation
* _3 S' m/ r/ [  \+ i{
; D7 [& L! j7 @6 ^: c3 c+ ]# E    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
) Z* b$ L7 {* P# {0 \6 r    {
$ h( k6 b2 n4 O5 I% Z        return new AddPostPayload(await repository.AddAsync(new Post( S3 u: p3 G4 k3 i. i
        {
( z! T7 o2 ?( j0 p. i' ~+ @            Title = input.Title,# H5 I$ R2 R6 s- s; o) b
            Author = input.Author( L8 ]4 U" M) e
        }));
! _! V) {: n3 `8 D    }
$ j1 U$ J. z, @3 B/ [  J3 {* n' e}
: i* f% k# p$ \" v/ r
7 `8 a0 J% a9 g/ F7 H7 v5 c: z</code></pre>2 @5 o" W, l1 C; r( x7 U: E: B
<p>最后在注入服务的地方进行配置:</p>
3 }2 ~0 V1 k& R% r& j<ul>+ S9 P7 A! q6 Y: {4 K/ p$ d
<li><code>ProgramExtensions.cs</code></li>
, [+ r' c! D2 O# d' D4 E1 Q4 ]' ]</ul>2 t0 V6 v5 i* n2 M: Y
<pre><code class="language-c#">builder.Services6 o( U; a; w" Q: G) q% W
    .AddGraphQLServer()8 @  C5 H' D/ r- r+ ]4 a
    .SetPagingOptions(new PagingOptions
% i3 q: T1 B' R' h. F1 c    {6 x, Q. }. K4 M2 y  [2 |$ k
        MaxPageSize = 50,
4 e. p% b2 c! e        IncludeTotalCount = true
1 }; q( J( V  K8 r) q' n+ ^* t    })% m- \8 C0 J: o: ]$ W
    .AddFiltering()
9 F; a! M; ]4 l9 m. V1 M    .AddProjections()
$ X5 ?, a4 k; L) l$ W4 y    .AddSorting(): e9 x: F# L+ Q6 S" ], W  _
    .AddQueryType&lt;Query&gt;()! Z: c; X& G  b
    .AddMutationType&lt;Mutation&gt;()1 M/ F" [  O! {% V( B. J
    .AddMutationConventions(new MutationConventionOptions8 i2 w/ ~9 X4 G: V
    {8 q6 `. _! \. Z+ _: p* ?2 h. M3 B
        ApplyToAllMutations = true,
  A' |& T. J, A$ Q        InputArgumentName = "input",' T; Q2 D6 g+ j. Y
        InputTypeNamePattern = "{MutationName}Input",4 V3 [. J. ?( Y  y: {  O, [- I0 l
        PayloadTypeNamePattern = "{MutationName}Payload",6 A1 q* \$ {% W  T
        PayloadErrorTypeNamePattern = "{MutationName}Error",
# i' x2 s6 Y  b' f1 ~" D        PayloadErrorsFieldName = "errors"
2 ^- c; g; }; j5 h. E4 c! w: X( }    })
7 D$ f$ k" L' L9 E    .AddType&lt;PostType&gt;();
. {* E* I9 J! \</code></pre>
4 n7 v' M5 j0 `+ X8 {<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
7 c( _3 L5 c. R6 T- P<h2 id="验证">验证</h2>
2 M  j, q- }- |  Y, s  F/ Y1 G2 g; L<p>启动<code>Api</code>项目,调用接口:</p>' w& o7 z5 f: ^# Y7 M: T4 F
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
6 V5 ~3 ~7 E' B2 c<p>终端的日志输出如下:</p>
0 ]  M% R5 |5 E3 `$ U- |<pre><code class="language-bash">[10:45:15 INF] Executed DbCommand (1ms) [Parameters=[@p0='?' (DbType = Guid), @p1='?', @p2='?' (Size = 13), @p3='?', @p4='?' (DbType = DateTime), @p5='?', @p6='?' (DbType = DateTime), @p7='?', @p8='?', @p9='?' (DbType = DateTime), @p10='?' (Size = 30)], CommandType='Text', CommandTimeout='30']
  h9 n; y  y4 Z7 M% i, aINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
6 c  E  k. T& p( TVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
3 k* I( V4 s* b! I( A* }% R[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
. |" H- Q1 ~7 r$ h% K. u</code></pre>! N7 h4 c! t% j5 R
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
# ^( a5 A% B; Z$ M5 S6 h& L/ M<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
. Y& Q6 \% G3 o% \<h2 id="总结">总结</h2>
/ F. V0 T# P+ l/ H, W" ?* N% e<p>在本文中我们实现了简单的新增Post操作,这里还有一些涉及到错误处理的内容,我没有在文章中演示,可以参考官方文档 <a  href="https://chillicream.com/docs/hotchocolate/defining-a-schema/mutations/#errors">Errors</a>,在自定义异常对象后,有三种方式可以进行错误处理:直接返回异常;使用异常工厂方法;使用构造函数。甚至可以在<code>AggregateExceptions</code>中一次性返回多个异常。基本思路都是通过添加属性<code>[Error(typeof(SomeUserDefinedException))]</code>来实现的。</p>
4 \$ J8 [) ?0 q. c3 u<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
' Y1 I  v5 U6 p4 P) k
0 u& a- |4 w/ _2 l
回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-9 15:17 , Processed in 0.081871 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表