飞雪团队

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

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

[复制链接]

8040

主题

8128

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

; N/ D2 d2 `: Y2 `$ Q( H; x<h2 id="系列导航">系列导航</h2>
+ Z' H3 F9 X0 a5 A% S$ p* C<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
+ Q  d8 L  t" Q<h2 id="需求">需求</h2>
5 V8 r8 e$ w9 T<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>' y9 p4 b  r; o0 t) h# v8 O5 e
<h2 id="思路">思路</h2>
1 u8 t# K1 b- ^* @; e<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
$ K5 ^; `( M( M  `! V<h2 id="实现">实现</h2>0 S+ @6 M7 w. X1 r
<p>为了保持简单,我们先定义以下两个类型:</p>7 B; Q1 h2 q. H' ~5 m. s
<pre><code class="language-c#">// 定义新增Post的参数: M- y/ f$ m' e; y) Y! T
public record AddPostInput(string Title, string Author);
* N9 G9 y- `' W7 M" o
+ v- |, z6 a2 |  m+ l// 定义新增Post的返回对象% p) B1 y1 X. m1 m" z! r
public record AddPostPayload(Post Post);9 V/ G% l. P) F6 s  U/ o4 z
</code></pre>
& l! S6 q* X4 @5 v% U<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
% V! n! p  |" q- N, a8 X1 x<ul>
) r4 m9 U6 F+ |0 \+ y<li><code>Mutation.cs</code></li>
7 [3 h+ K4 B7 e/ k5 I$ b' v</ul># g3 s+ N/ N8 q
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
. z. ~5 ]4 p; ?! ?' r9 _  b; o* b; V+ F( V8 q. t  g- G( G& `' q
public class Mutation
3 W+ T1 V) o1 e1 n) k% r{4 b5 v( J2 n$ O# D6 O. I
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
6 r( v8 q. }5 ]7 U7 j1 \/ t1 a    {/ }& D! j' R) Z  F
        return new AddPostPayload(await repository.AddAsync(new Post$ u" q7 }0 m# P8 D0 M) K# ~
        {
8 c4 j) b; n9 |1 U( O            Title = input.Title,
: ~( E) g0 d) x/ W9 l            Author = input.Author
; c. \: K- }3 }! x        }));: W: `/ r2 S$ h+ k7 \6 `" b
    }+ o: z; @/ [. y( u1 B: L, h
}
/ c+ B; g( g8 d  W1 J1 S8 a
3 p" [$ r' }% o2 |6 ?' ^3 ~/ _6 w</code></pre>; {* \' [8 \4 I' @( I9 B
<p>最后在注入服务的地方进行配置:</p>
0 B) Q- N2 h9 Y& V& ^0 M. P+ p% ]<ul>
: c* A7 Z( u% Z/ P4 e<li><code>ProgramExtensions.cs</code></li>
" O  S: \* [  V" B  g( N</ul>
( R( ^. U9 J  [- s  U<pre><code class="language-c#">builder.Services
" H0 g! E! c+ t" R    .AddGraphQLServer()
5 V0 q( y* u8 S4 S, G$ i# {& E8 I    .SetPagingOptions(new PagingOptions, q) X+ o; j, [" M- F4 ~
    {
& D% B1 ^0 t; m, g  K2 y5 t# r        MaxPageSize = 50,
  A. x" N# ^, V- v+ u" C        IncludeTotalCount = true
8 L( e# W) N" y! f' u# W    })
! s% R+ D+ G" ?1 {! G; L    .AddFiltering()
  k. K' N- [3 e- ?9 C) d/ t    .AddProjections()
  `3 ^+ Z8 a# t" i. w    .AddSorting()
3 n7 X2 K) n8 |9 ^+ P5 i    .AddQueryType&lt;Query&gt;()5 n% {0 R8 S2 E) _  v" j
    .AddMutationType&lt;Mutation&gt;()
# k( M6 r+ _/ g( y& k    .AddMutationConventions(new MutationConventionOptions% }  W4 n+ q6 L: M3 e) u2 N
    {( }: N6 ^% w" `4 d, r4 a5 Z/ u
        ApplyToAllMutations = true,9 w1 X( n& [4 a3 r- T1 D& g5 M1 `
        InputArgumentName = "input",9 a& v/ A  r4 v% L
        InputTypeNamePattern = "{MutationName}Input",
6 g0 g- B( f# ]        PayloadTypeNamePattern = "{MutationName}Payload",; u2 }! S& G: t  u
        PayloadErrorTypeNamePattern = "{MutationName}Error",
, K# @. |# _6 ]# {. P$ H$ N1 P        PayloadErrorsFieldName = "errors"
5 s7 \+ I& \4 M' `# h* _- ^. H5 _    })
" f1 R; G& n, S- U6 U/ A    .AddType&lt;PostType&gt;();) K# b! w6 ^) s# v1 B% Z. |5 l
</code></pre>
( J' q$ B) {" U* S<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>" z: M/ K6 _" r  I' x
<h2 id="验证">验证</h2>
7 h  {9 c3 [" V" r) o% ?<p>启动<code>Api</code>项目,调用接口:</p>
; e8 V7 \0 O/ e  s& p. R! q# t* @<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
  Q" Y9 W) q9 @7 P" u<p>终端的日志输出如下:</p>
0 \3 L0 E4 B3 T6 o( L- l7 o1 n<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']
6 I( A1 F3 D& N- OINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
* e0 @! t$ p3 m" U+ w5 WVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
1 @3 O8 e! g, h# D[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'" f# m% l! b& e! }
</code></pre>
8 P  {0 c2 C, m3 s; G6 R<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
3 \! z+ m; m6 H; X$ @<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>" N2 A" G4 {. H; S# F
<h2 id="总结">总结</h2>
) I' K+ g. a: y/ X<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>* e- l& H" J% F" C, J
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>$ p7 G: e/ ^6 I* t5 U' j
" X6 r3 R. m/ C$ Q9 X
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-6 12:26 , Processed in 0.063742 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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