飞雪团队

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

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

[复制链接]

8058

主题

8146

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

3 R7 Z/ a5 e" Z6 R<h2 id="系列导航">系列导航</h2>
, I* y! k: U( S* w  u' G<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
. P+ P/ U1 N. a) x, c9 p<h2 id="需求">需求</h2>7 ?, q8 M( {2 m3 j+ m
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>& l1 o6 s) }/ e  h3 L
<h2 id="思路">思路</h2>/ l/ d7 I1 g( E8 ]* ^
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>6 Z6 G6 @; _- \$ w' c8 _, W
<h2 id="实现">实现</h2>
, w6 s0 i6 K0 @; P  d- }2 D) c# S! g<p>为了保持简单,我们先定义以下两个类型:</p>1 C  i+ ~7 @- H$ Z: f( c% N% A
<pre><code class="language-c#">// 定义新增Post的参数0 i1 q$ q) Y4 q. D/ W
public record AddPostInput(string Title, string Author);
/ \. r% l3 }3 f! J5 z. C  J7 o& J% o( Y8 I
// 定义新增Post的返回对象/ ^& M3 G; B, R' z6 F( y0 ]: n
public record AddPostPayload(Post Post);! I5 W9 l/ A% L  B8 p* w
</code></pre>
% S" o& f/ N" i* f. r9 R% |<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
, c) ~- k$ M1 }<ul>  ]. j7 ]$ W( s3 _* |
<li><code>Mutation.cs</code></li>
; g% C7 W) d8 W; f2 j</ul>
0 a  y# V5 d$ w5 \3 t+ ]  Z0 D<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;. b, `; G8 \7 D* C
! ~% P" ^$ j" i" v; p
public class Mutation/ Y' t% l3 z2 V4 z
{
, u' ]7 O2 Q" _7 |" r) v    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)% D* G* ]7 q7 f5 N; }
    {% l4 T' s  d2 Z% \) j' H2 P
        return new AddPostPayload(await repository.AddAsync(new Post- q6 o, V8 o0 K) Q8 ]) w" O1 v
        {
5 R1 z7 b: D5 q- Q# c! A            Title = input.Title,  g7 C" r: a+ G& c; n# g
            Author = input.Author  g' d) {- b* M- J7 x* V
        }));3 T& H; J. ]8 M  @; M
    }
6 R% M, D% m" J9 X) a. M3 O( D  I; ]  b}
- ]8 I- N) q- J
0 E7 I; n- T9 ?# h+ Y8 q" d+ v5 O</code></pre>
5 v! N+ T% u8 }  O- Z! L2 `, U<p>最后在注入服务的地方进行配置:</p>
% `% b( J2 @3 e1 S<ul>
6 X: P$ Y3 a+ E% J* D# r<li><code>ProgramExtensions.cs</code></li>4 U+ c# x, \& ^* M- G  s
</ul>
- o+ v7 B; _4 D; w; d$ c<pre><code class="language-c#">builder.Services
0 `" f7 B# b+ {: T7 W    .AddGraphQLServer()
- _: j2 _* L8 M    .SetPagingOptions(new PagingOptions
/ X/ b5 C" b2 g7 E4 G. m% E    {
3 K0 p% ~" F# p/ f. i% i        MaxPageSize = 50,5 c  E9 p; b* |
        IncludeTotalCount = true
+ y; u# ~- o8 e    })& O5 E0 X1 f6 J- A! v
    .AddFiltering()
' K, m! F' l! I7 G    .AddProjections()
- B7 b4 x, @* U6 o% L6 m2 ?4 X    .AddSorting()
2 B4 t2 i! j* k6 U    .AddQueryType&lt;Query&gt;()  E, L. E. ?* Q$ \& U8 N
    .AddMutationType&lt;Mutation&gt;()0 \' c8 r* L" Z. C' B
    .AddMutationConventions(new MutationConventionOptions
( z* ]1 h0 |" u7 p" s# v7 U    {9 ?" g; u# d8 z
        ApplyToAllMutations = true,
" x+ |3 D* W4 s. w  Y* v# @( K3 y5 w        InputArgumentName = "input",1 f' e; }& j, v! O+ J
        InputTypeNamePattern = "{MutationName}Input",
5 m- g* d/ l# L" q        PayloadTypeNamePattern = "{MutationName}Payload",
) g1 b9 {7 ^0 B6 D5 t1 ?        PayloadErrorTypeNamePattern = "{MutationName}Error",
9 z# C! Y- D$ K# Y+ x        PayloadErrorsFieldName = "errors"$ V9 d2 _1 Q$ c
    })
" X) f) F* B' o6 C3 G# _& _    .AddType&lt;PostType&gt;();
- _3 Z: m8 N7 A! O</code></pre>
2 C+ _& G) m3 }3 l<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>$ x* m) L- P8 R' D4 l
<h2 id="验证">验证</h2>* G  Y9 ^% ^( E% b9 i3 E) D; N
<p>启动<code>Api</code>项目,调用接口:</p>" Z: }$ n& P. ^! Z/ N
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
1 ^  _7 j/ U) \# e( z9 w0 P/ ^' z<p>终端的日志输出如下:</p>- u; e+ V4 |; f7 @6 ?6 ]
<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']' C0 \6 d" O! g+ ~0 O+ F) D
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")* V+ H4 M3 R% g4 U7 u/ Z
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
% ~1 H: y! }2 b/ n  p' ~- l7 y$ r[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
. H) @/ ^/ s" _# W- D8 r</code></pre>7 d$ I/ ~$ \8 x5 F
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>0 o; C1 b- j& I, U3 \
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
4 D. e* y  H3 D: y<h2 id="总结">总结</h2>9 o7 P+ f: Q4 X1 {/ [( a, _7 Z1 x- 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>
! F) J, ^- G$ O. n6 y: _; j' @<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>1 @" I+ m$ L! H2 l
. K1 q" T8 l7 y5 {" i* ~
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-14 07:31 , Processed in 0.064303 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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