飞雪团队

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

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

[复制链接]

7952

主题

8040

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

# T3 S6 J& w6 d: V% j& m9 \! w<h2 id="系列导航">系列导航</h2>' u3 k6 \  ^7 A' Z( h0 v
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>( u# R2 j- v! V+ _, k/ I2 R
<h2 id="需求">需求</h2>
+ Y# z3 |# ^6 `5 [- @/ j8 b8 P) F<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>$ N/ f/ M% V: s/ B1 [/ b
<h2 id="思路">思路</h2>
% s5 P, x# d' {& \) r' s<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>& d0 A. T0 A5 h) _/ l% S1 V
<h2 id="实现">实现</h2>+ c% Y# d4 Z$ b1 t5 Q% x" {
<p>为了保持简单,我们先定义以下两个类型:</p>- g, }( O. O# E7 p& |1 F' d' w
<pre><code class="language-c#">// 定义新增Post的参数6 c: Z" I3 B* K
public record AddPostInput(string Title, string Author);
% u! T  I) T2 ~5 N4 Q& t& t0 v/ o
// 定义新增Post的返回对象
/ n. n8 a% Q2 D0 o, K' X# \( Npublic record AddPostPayload(Post Post);
! u- a% s( K) [9 ?0 \, x1 l7 {</code></pre># b4 ?2 y- }$ \; F* t1 r8 r0 x
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
) p# a7 A' F  \! v  U3 d( P<ul>
1 o& i3 H* z! C( s  c<li><code>Mutation.cs</code></li>" B: j& K1 J$ l
</ul>
( W. i. f( W) }/ M3 M6 K. D9 `<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
3 ]1 G' ~' r4 t: R+ K. f. _+ r
6 `9 T% A" _! d8 vpublic class Mutation
6 G! R& w& N% v1 R& G6 g4 @/ o{1 p$ y& W- _# c
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
! f$ j) R; l( _+ Q    {9 X! {: {' H' Y- r+ {
        return new AddPostPayload(await repository.AddAsync(new Post
+ v6 o  ^# k9 n# w: |  j, ^        {
% o/ ?) X5 M/ u            Title = input.Title,6 N9 l5 Q& d3 G" g2 h) ]
            Author = input.Author
; V4 ^2 I* H7 N. a% v# A2 F        }));/ Q5 n. V5 {0 J: x5 ]6 x
    }5 O8 u. F8 l- n( l  t( H
}1 l: U* |" w4 O
) y! T5 a3 Z+ \, b* _$ I
</code></pre>
- F; k; e3 J$ @! K<p>最后在注入服务的地方进行配置:</p>
9 D, a( q! L: _& [- s3 y<ul>
1 U% @! [, `" U" `, V. I5 O) h% k1 r<li><code>ProgramExtensions.cs</code></li>
/ @/ M# w* m+ ]8 p; u" u6 @</ul>. n) z# i; N% J7 ^1 |: A; H. K
<pre><code class="language-c#">builder.Services
) V* Q( H; s2 R# j5 l& w( e    .AddGraphQLServer()
1 {1 H5 x/ l. I$ f0 x5 E* @, [    .SetPagingOptions(new PagingOptions
6 a* Q" W8 m2 M; l$ m/ z0 f/ Y    {* J' {9 U0 `/ ^+ l7 r. R
        MaxPageSize = 50,
/ |. |; e" \: I2 o5 k9 h  C        IncludeTotalCount = true$ _$ i* }1 a+ y8 b  Q, M  }
    })
  r% q  H8 \( r5 H7 X6 K$ m) K    .AddFiltering()1 n; h2 Q% z: g4 _$ Y% m: K
    .AddProjections()1 u+ e; J: l0 U4 b. [
    .AddSorting()
! [9 `4 m) [  F1 R" l: u% G    .AddQueryType&lt;Query&gt;()) V: ]1 c/ y2 `* `
    .AddMutationType&lt;Mutation&gt;()
( M5 ^! Q0 W7 A( i5 \0 v! g* w    .AddMutationConventions(new MutationConventionOptions
/ Q3 u* {& V8 l, A    {
6 v) ?- l3 F4 J8 o/ m5 X3 b! a; W        ApplyToAllMutations = true,
! W* N" l/ D9 W- w; G8 M        InputArgumentName = "input",
3 R( p$ {9 _* i5 f3 V& n& y        InputTypeNamePattern = "{MutationName}Input",
/ N9 Y1 ~) \7 o1 g  X) Y        PayloadTypeNamePattern = "{MutationName}Payload"," }7 |# e/ P1 h/ o: w/ r: t; w
        PayloadErrorTypeNamePattern = "{MutationName}Error"," w2 H$ y. Y5 c7 F7 Z" Y7 n/ o
        PayloadErrorsFieldName = "errors"
2 ^6 G) v, E+ f! B! g0 t    })9 f" B9 K5 j- K+ N
    .AddType&lt;PostType&gt;();
, t1 t. v; _& A! }/ I6 @</code></pre>
$ u7 u; |: l% w<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
; a; \9 [9 H% B<h2 id="验证">验证</h2>6 ^! C5 S$ {; ]
<p>启动<code>Api</code>项目,调用接口:</p>
5 ~' r* O$ j7 |3 b. d<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>  K" S) x0 q6 n2 D. `% K  `
<p>终端的日志输出如下:</p>4 Y" j, G0 w8 ]) v
<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']
' C8 `# H- K3 G. PINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
: n) H1 R5 D* d$ X, G% E1 I8 V& s" UVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
0 k5 s  V9 z6 @# K[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'0 _3 @5 T' N4 }2 u# T- o4 W
</code></pre>* c" B2 S, \5 K+ N: O; A: Z
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
4 m  H1 {# @$ B& T* P) y5 n$ @<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
$ w6 i8 p) s: a; ^0 n<h2 id="总结">总结</h2>
9 A; n; ]9 _6 b# I: }8 p8 Z<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>
7 S# t# h( Z8 r" V<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
. p. K8 N# l/ [: }. V" u% N- p4 u' u, c" B5 E9 y3 y
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-24 03:27 , Processed in 0.069099 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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