飞雪团队

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

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

[复制链接]

8040

主题

8128

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26450
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
) H7 H$ k: V, |: b; ]7 c1 F9 U9 }- p
<h2 id="系列导航">系列导航</h2>+ u: h9 _0 T4 ]- r6 U# n; g
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
7 J0 @3 Q5 \3 x. q6 P5 j% M<h2 id="需求">需求</h2>
0 {3 J% p+ B- \, v: E<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
3 w5 a/ s2 N6 T8 i<h2 id="思路">思路</h2>
  q% C% N# x# j  o, R<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>( ]! Z- U+ n2 O4 w7 |6 A
<h2 id="实现">实现</h2>
( l) s; i$ |$ p1 f1 ]1 X6 E; n<p>为了保持简单,我们先定义以下两个类型:</p>! v8 n( y. N) q; a4 w- Y: H" |2 d& B3 B
<pre><code class="language-c#">// 定义新增Post的参数7 Z% Q( w7 ?' Z, e  O4 p4 D
public record AddPostInput(string Title, string Author);
, ]  V) @  m2 J( ~) A# x9 n: l4 |: S' J1 v1 K3 A* g) U
// 定义新增Post的返回对象
' I5 O7 t5 Y2 ?4 K. [public record AddPostPayload(Post Post);+ c, l& d5 v- O, |  C9 ?" p9 F
</code></pre>! L6 Q' J/ |7 \% W; n' r
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
5 U8 A! f" \6 I. m<ul>( W4 M0 d* ]* Z
<li><code>Mutation.cs</code></li>7 T0 ~) d  ^0 e
</ul>. P+ `. H; U$ ?3 E
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
  n" z6 n$ \8 e3 m# S+ ~. p6 c4 x
public class Mutation& B0 n" {4 m  ]5 Y7 a: }, w
{- u; W5 Z  X( b+ j: R. `" |
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)& ^0 O& X+ |* y( ~# b
    {6 Y6 d+ S% G. U! M* ]) v8 d
        return new AddPostPayload(await repository.AddAsync(new Post
+ x& Q0 Y& \8 h3 V. a+ X        {' ?5 t* J2 g" f1 {/ y& N0 h9 k
            Title = input.Title,* {( Y7 A" R- P* `& O+ t/ }
            Author = input.Author- z4 {2 }$ p6 D5 @' m5 X
        }));
3 ]1 q8 N6 r8 O8 s    }
- a  @3 S+ M: p  a; l+ u1 T" x$ |}' I5 @- Z/ v, B* G
1 e. {: y8 U. |# ^7 g- c6 J
</code></pre>: x: z. b2 x" G( ^2 a; x
<p>最后在注入服务的地方进行配置:</p>; J4 o: E7 U2 @$ l% @/ |) }
<ul>
9 T  s0 h$ M! o' h: N: C+ |, h<li><code>ProgramExtensions.cs</code></li>2 c" l$ v4 H# }+ f7 n
</ul>
( k6 S: b) Y4 l1 h" Z8 L3 t* ^/ X- I! S<pre><code class="language-c#">builder.Services
3 i0 N9 j! i9 D& p    .AddGraphQLServer()
6 q7 v" t/ m5 [  X! K! H    .SetPagingOptions(new PagingOptions
! I- u( }' i9 d; [# z/ {+ k0 z    {5 [* K& A- C1 Z
        MaxPageSize = 50,$ m8 @% ^$ t: m/ i7 a( R
        IncludeTotalCount = true+ y* V7 `5 D3 s' X& s0 M
    })
( q+ I! @7 h" k    .AddFiltering(); }0 ?" j0 B/ t( c
    .AddProjections()% g; f, n! _1 @% P4 I6 p9 B& D
    .AddSorting()- ]- K, S2 ^: ~4 _9 q$ X
    .AddQueryType&lt;Query&gt;()
# p5 p+ W; x2 P* q# W    .AddMutationType&lt;Mutation&gt;()
8 h% o3 u/ X# Y! i' X4 {% c7 F2 H& \$ @    .AddMutationConventions(new MutationConventionOptions- T- c* t# x6 L8 E/ N
    {
: Y- L$ y9 u( V4 ]+ z# N- w        ApplyToAllMutations = true,; K4 M; v/ |# i! Y+ W2 R0 @* Z. E
        InputArgumentName = "input",' G  q/ b6 D+ O, B3 q5 A5 v
        InputTypeNamePattern = "{MutationName}Input",
! V0 y/ V. S6 A+ {  c+ S' f        PayloadTypeNamePattern = "{MutationName}Payload",
+ G6 e" ~9 D" o! M; F$ i        PayloadErrorTypeNamePattern = "{MutationName}Error",
! ^! A- ?. B; }        PayloadErrorsFieldName = "errors"
" W- `% y  {5 n# d3 Y' q, g    }): N  y$ `' {5 l$ z& O5 Y  F
    .AddType&lt;PostType&gt;();8 p, r, `- p; @0 Z, y( J
</code></pre>2 U& I& r. D! U
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>* k4 b" o5 C7 U1 r" U0 E! y
<h2 id="验证">验证</h2>
1 e7 H& F: }9 [6 L<p>启动<code>Api</code>项目,调用接口:</p>
$ J' J) o  V" c& I1 }" e6 w: X6 h<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
5 A2 f. M3 k3 N. E<p>终端的日志输出如下:</p>0 Y& L- Q" {4 |9 R% G. `( P1 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']
  b) m% n5 ^" R' }, p. `INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
" ^, X; I4 p* U6 _) dVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
0 P6 A6 j( i3 `1 B[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline': I5 z. [! Y5 v+ f7 Z
</code></pre>9 Y1 W8 E8 _' F& L
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>8 m7 d# d$ H% B( U1 d2 ^
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>. v' }' ]) y4 s/ c  S: f" e# F* @
<h2 id="总结">总结</h2>* f+ y4 ~  M( p1 l2 x  W
<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>3 I- x" R% r5 R& t/ w3 O: @" c
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
9 s2 i8 w1 s$ }# {. E. }+ D/ B4 \9 S1 W' Z! ], c" C
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-7 10:05 , Processed in 0.063869 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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