飞雪团队

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

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

[复制链接]

7992

主题

8080

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26306
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
, ~3 Q0 E1 Q. ?4 Y* K  g1 H
<h2 id="系列导航">系列导航</h2>
% j; x" y! T& i: i+ t) K/ E<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
8 |% y9 i- I7 g, D<h2 id="需求">需求</h2>
  g: u" _9 G5 m) R# H<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
8 _% `$ l* d$ k<h2 id="思路">思路</h2>" J0 B+ {0 w, ]1 T
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
5 L$ |4 k: n  @) a+ Q1 j" A( r<h2 id="实现">实现</h2>3 m2 f2 o& T5 b. a) S4 {
<p>为了保持简单,我们先定义以下两个类型:</p>0 m# u- I7 c* t* ^8 ~% l4 u' B
<pre><code class="language-c#">// 定义新增Post的参数2 t- K" `- i/ n
public record AddPostInput(string Title, string Author);2 n3 q$ E; ^1 f8 ?2 |# A/ j3 I
+ `4 N  a$ A0 x! Y. r! K/ a+ w
// 定义新增Post的返回对象- q( S! W9 ]+ e
public record AddPostPayload(Post Post);
- f0 e* r* O( B& n</code></pre>; R) K3 W( P; J' m9 C- h* g
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>' w+ F* j8 o4 [; m
<ul>, g- z8 e- ~5 b8 E9 E3 j
<li><code>Mutation.cs</code></li>7 ]8 ^& Q( U' B0 o/ ^- g! W
</ul>
: D6 Z" e- M9 @) z<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
& r# a" A* C$ L+ y9 _% C* w6 N" j. q/ e
public class Mutation
. V6 N9 M/ x" M( j6 Y{# D9 N& E- {4 A3 i
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
; d- z4 N. j- _: r    {
$ r4 c0 N3 F) z6 y6 a        return new AddPostPayload(await repository.AddAsync(new Post3 y: `2 d. [  W
        {/ X  p- D% V: O
            Title = input.Title,0 A9 N" r1 Z# O* j
            Author = input.Author
6 R+ C1 L, T& y7 d+ a        }));
- S! m9 u( h$ K8 M+ R8 i: U! |9 ]    }
. u* @% C* A6 a5 J) D. ~; t}& e4 V4 b, ]5 T# u/ @
% N9 ~, R3 b) w  w* X4 R* i
</code></pre>5 h6 F  d9 A8 {7 x4 y
<p>最后在注入服务的地方进行配置:</p>
) q. d1 B, j& U* M6 h- g( @' x<ul>( Y) |) k% ?) a! [5 k
<li><code>ProgramExtensions.cs</code></li>, s% {# k+ |' o3 Y
</ul>
$ x4 @* r1 q. K( {1 y<pre><code class="language-c#">builder.Services
" y) Q$ W5 N  u- [. m: X    .AddGraphQLServer()
& m8 R: [( H' f/ J* L) v, G, i    .SetPagingOptions(new PagingOptions
- X  E+ }% o- a3 J, T    {
7 ~; u4 T% c  e6 `4 D        MaxPageSize = 50,
, ~, s- p5 J( a7 K& ~3 f& m' D        IncludeTotalCount = true
0 j) E7 n; n' M3 T    })
' m, r+ N$ L# B, }: Z9 e& |' `    .AddFiltering()' [- ^  W$ U+ g, L+ T: V4 @, m; a
    .AddProjections()
+ N$ U* n. x+ _& j7 I% S9 K    .AddSorting()
. \+ _4 Q6 v" h9 i# D' ]( Y* ?8 R    .AddQueryType&lt;Query&gt;()' r8 c$ i* ~/ Y7 N
    .AddMutationType&lt;Mutation&gt;()
( |( q* U. S! @- u) y    .AddMutationConventions(new MutationConventionOptions
7 H* |8 D. G5 I, L3 _+ t    {  X- h% h, X) l6 T) Z; K* u
        ApplyToAllMutations = true,- v" y- c2 t- Z- N5 H+ U
        InputArgumentName = "input",) C6 W6 ~6 u# G* o7 L
        InputTypeNamePattern = "{MutationName}Input",' K0 r: d( N3 M. K, C! Z
        PayloadTypeNamePattern = "{MutationName}Payload",& {) \- a5 J1 H: h( u+ w! E3 h3 y
        PayloadErrorTypeNamePattern = "{MutationName}Error",  a5 X- p. f( z: R
        PayloadErrorsFieldName = "errors"
6 e  o1 X/ w# t2 ~    })
& N) c' M- d2 h3 V! c2 R    .AddType&lt;PostType&gt;();4 T9 L/ p! E; n6 q) {( A& ~
</code></pre>- Q$ v+ b% a6 Y% H/ T& l* @
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>& P  B* Q. T+ {" A+ H: W7 e
<h2 id="验证">验证</h2>
6 ]* J+ G2 \) S<p>启动<code>Api</code>项目,调用接口:</p>- c* j* `$ M" y) e0 C
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>. r( r, e7 i, L/ M
<p>终端的日志输出如下:</p>
  `+ P( n0 K  z7 o/ N1 I5 ^2 W<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']+ Z: v) |. X! m; }
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
" w% |0 |8 w, w+ z$ N9 GVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);, t4 I- y  j" ^2 U
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'% {2 h" f7 G8 r' u2 L
</code></pre>" l) Q, p  A; I  @
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
* Y' \5 N* h  T' |2 Y5 ?<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p># n; U& I2 d6 Z" x# h1 ], U
<h2 id="总结">总结</h2>
7 l6 z! h8 {8 h8 J5 O0 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>
" q4 T* s: E$ W% a: e' i! j/ j<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>) B" w, c) ]7 z1 m* p
* X9 n9 G1 E8 n4 g6 `" [: W9 O
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-27 12:56 , Processed in 0.098220 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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