飞雪团队

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

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

[复制链接]

7957

主题

8045

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26201
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
' `: O. U$ i- ^3 G0 w- f
<h2 id="系列导航">系列导航</h2>
* m1 y+ z, Q# k: \<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
2 n6 U+ a- D7 k' G* |# X' \<h2 id="需求">需求</h2>9 T& V9 H, U; d+ W
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>! n: A8 k- a2 j7 ~1 \
<h2 id="思路">思路</h2>5 Z2 G  b8 ~' f+ g9 L
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
( C* ?# P9 p- r) w; [<h2 id="实现">实现</h2>0 T  c6 r. k2 Y$ F. d! I
<p>为了保持简单,我们先定义以下两个类型:</p>& V$ A' P1 T  |0 t* \
<pre><code class="language-c#">// 定义新增Post的参数8 i& A# w0 D) V1 ?. v* F" m: a- ?
public record AddPostInput(string Title, string Author);
4 v$ l! w! j* z+ l; p. K1 i( f4 n6 I- V6 g4 t
// 定义新增Post的返回对象
2 u: X  K( X4 ~0 d' lpublic record AddPostPayload(Post Post);
' |; t0 d# p4 ?* m' q</code></pre>3 i7 |$ A% g1 }5 I+ K' e
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>' Z" ?7 [; \( S: ~/ `+ [$ I
<ul># l: M/ g, B2 ^# G. G! }% a
<li><code>Mutation.cs</code></li>
. q8 G; Q0 s  p& ]</ul>
/ a$ r6 `* }% [3 w5 X+ F<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
9 t2 A8 o+ L( Z" K+ c: F
5 n- n8 w# \! {% Fpublic class Mutation
7 c0 a1 E+ t" u# O" v, `9 A{6 _0 u  E" l: W7 F
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
- o* J. A6 d) |    {
& h% b* ~" v& j/ v% X! H        return new AddPostPayload(await repository.AddAsync(new Post1 K# K4 o/ n9 V8 G
        {
: A4 Q: L6 [7 Q3 ~7 ^. ^7 z            Title = input.Title,6 I) H" ~; Y. m, l% F6 ?' K
            Author = input.Author
( ]; _: Y) y; K7 w        }));
& y9 b3 |& j1 ?( V4 n    }
. T$ h- M* Y" s3 h0 R0 ^}
, ]3 n. X% ]$ K/ U' x0 l
2 l- t( Q8 R' M+ G9 r1 K/ U7 k</code></pre>" `5 ~' B$ F/ F9 N& l2 P
<p>最后在注入服务的地方进行配置:</p>
# \% D: T; P9 }2 R<ul>, M! |3 Q+ I. P! h# a
<li><code>ProgramExtensions.cs</code></li>
7 \) S1 F9 V- u: e+ |- V</ul>
3 o/ |# w0 |* M8 n& }<pre><code class="language-c#">builder.Services8 ^- J* E- t1 x0 x& h4 Z
    .AddGraphQLServer()
5 @' s9 c9 ?* b/ b    .SetPagingOptions(new PagingOptions
2 [" X/ _2 ~/ H/ T3 |    {' ^+ R" \* K3 W8 a
        MaxPageSize = 50,6 Z. Q2 E+ ^* g! |1 B& H+ @( g
        IncludeTotalCount = true
7 h9 a4 H! D3 w0 \  ^    })
! N% C/ {6 @5 n, q5 C; q% ]    .AddFiltering()
: q: u4 @; p( D; W# j    .AddProjections()1 H3 w" }+ d: k/ O4 L  b2 n; y
    .AddSorting()" M$ V& r( L; `' A- x7 q8 |5 w- K. H
    .AddQueryType&lt;Query&gt;()% Q0 v5 t0 r* c6 Q" d  A3 Y
    .AddMutationType&lt;Mutation&gt;(): `8 d. E, A$ }
    .AddMutationConventions(new MutationConventionOptions
0 p. c2 t/ q. i$ S4 v5 W3 w    {5 p+ Y7 J9 x9 P3 Z
        ApplyToAllMutations = true,
" R0 Z1 \* r2 S: v. n& L. i% {8 y) C        InputArgumentName = "input",+ a$ T; T6 \  @* B& P7 Q+ c( r
        InputTypeNamePattern = "{MutationName}Input",
4 }9 q) B9 z' ~5 d        PayloadTypeNamePattern = "{MutationName}Payload",& g, O; m9 v' M4 K4 [7 Y
        PayloadErrorTypeNamePattern = "{MutationName}Error",
/ D1 j4 r. i9 k0 L        PayloadErrorsFieldName = "errors"
! c' C3 x, a* s% ], l* n    })* z9 S& \' h* @5 L. B( {
    .AddType&lt;PostType&gt;();3 z8 i& A" o" p% Q
</code></pre>1 t# R0 G" v7 l) l, R$ v6 O
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>$ [' l" V' v1 L
<h2 id="验证">验证</h2>
. c; d" `. w# z8 `; Q7 |" j  w+ N<p>启动<code>Api</code>项目,调用接口:</p>: o/ q2 L1 b- e. |( S2 R
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
1 N; j$ m0 T0 P<p>终端的日志输出如下:</p>8 |$ Q( k0 Q5 l3 K3 {3 P9 d
<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']5 Y# A* B- m) [
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
5 C# }- u/ c! L+ \# i0 A  EVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
( C9 z9 D6 i- Q) P7 ]6 x( X[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'" M* ^2 x! I& Q, |
</code></pre>! f* f1 R* T+ ^2 R! b
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
; E( l" C9 x2 A9 W<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
$ b1 I0 ~- W; r8 S0 ?/ n3 N<h2 id="总结">总结</h2>
' E* Q2 a. r/ x3 d2 c$ L3 k<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 i  V/ x4 H3 P% R<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>! U! |4 l* _8 J- [9 w8 I
. T3 V, E2 F/ P% y- `
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-26 10:42 , Processed in 0.062599 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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