飞雪团队

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

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

[复制链接]

5344

主题

5432

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

4 G7 w$ e) \1 V" A- p<h2 id="系列导航">系列导航</h2>
2 {; B" o: h2 v$ J' H<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>- H. _+ {9 Z- U7 s$ k# d
<h2 id="需求">需求</h2>; [5 g; J! T0 o3 P- d
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
. B1 T. H/ k& V$ Q/ D- y' w<h2 id="思路">思路</h2>
+ U8 `- J0 s# U6 c$ I<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
+ v8 {  v! ?) I" z/ @1 H2 [<h2 id="实现">实现</h2>
' D# O2 W, h% a" l# z1 E! z+ n<p>为了保持简单,我们先定义以下两个类型:</p>3 E7 b) |6 [/ y8 L) w3 j
<pre><code class="language-c#">// 定义新增Post的参数& O3 b8 p% k" W- ^$ s
public record AddPostInput(string Title, string Author);
. G' F9 A/ C, U' u3 Q% v) R8 o* h
// 定义新增Post的返回对象
( w. x5 B/ R/ u# p, _public record AddPostPayload(Post Post);
1 J% Z/ P- A6 C) W</code></pre>, O, E5 {0 |4 S. b$ p+ v# K7 y* C
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>8 \7 s. q' ^; A% L$ \
<ul>- t6 l. e7 u* {1 f: z7 N- B* ~
<li><code>Mutation.cs</code></li>1 W- f6 T9 f! a5 \7 y: S, Z
</ul>7 E/ h; N' Y* P* z+ n" I' Z
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;" ?) O  V9 c! F- e" @6 _
/ R& r% a3 b& o) \# o. X
public class Mutation; ?. N/ I- y0 W9 ]) _9 B* ]
{5 t. X3 P3 Q( _- I2 d5 I
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)( f2 j* H' |. c& ~& L
    {
) x8 O7 G: A" K: h  n        return new AddPostPayload(await repository.AddAsync(new Post
: A2 m; X2 f% }( J        {9 k/ M3 c' A# X; e8 A( x+ k
            Title = input.Title,$ ^. p/ @9 P+ w( S3 ?7 L
            Author = input.Author9 O+ T3 b/ X1 @& B, z4 N  Q; j7 x; h
        }));! c; j- }+ ^2 S; A1 g
    }6 T( y3 j% ^% A( u! y! S+ B* Q1 ?
}
' u& W0 j2 n% U2 f
, q. Y, N( M  m: J# W% ?  {6 E</code></pre>3 n/ r) Y! ?; Q4 B+ t1 X* x
<p>最后在注入服务的地方进行配置:</p>
$ y" P2 Q  P: T' ]7 R4 z6 |4 Y<ul>
4 M; x& ^) I6 l7 w$ |# f! r( ^<li><code>ProgramExtensions.cs</code></li>
1 f6 l" M* B1 C4 k7 M% w- ?</ul>
; u- u9 U; Z& y' ]- z/ Q<pre><code class="language-c#">builder.Services
# W+ e, T( m3 u, n1 O0 Y/ Y    .AddGraphQLServer()
+ G% j6 _# x( b1 a1 S. K1 o    .SetPagingOptions(new PagingOptions
! F( e9 R+ l9 l/ |9 X& ]0 w    {
: \- r* g2 }. D/ R9 A" y        MaxPageSize = 50,
5 F, X/ K" c4 w/ P& \8 D+ I; A        IncludeTotalCount = true, ^4 W7 h2 F- G& v/ z/ X
    }): u# x5 f; t- F4 g
    .AddFiltering(), M: s5 B0 K8 a8 @4 w0 v5 X3 k
    .AddProjections()/ B4 C' t( x$ P% ^: g
    .AddSorting()
* o) t" M) n& b" h0 W/ i    .AddQueryType&lt;Query&gt;()7 ?3 {- V2 m& p9 g; g+ t
    .AddMutationType&lt;Mutation&gt;(), R& M# a, s: j) v2 t+ T
    .AddMutationConventions(new MutationConventionOptions3 K9 }" a( g" c- U6 U0 K/ B
    {
( J2 s- v7 E" A0 r- G: Q% N        ApplyToAllMutations = true,
' z. w# I: C7 o! e        InputArgumentName = "input",: D2 ~; O  V6 O8 u" N5 p( x
        InputTypeNamePattern = "{MutationName}Input",0 @) f! C$ `/ x- L9 O
        PayloadTypeNamePattern = "{MutationName}Payload",; e) r* {' y$ U( D3 a: m$ C
        PayloadErrorTypeNamePattern = "{MutationName}Error",
  G4 }" `) U  }! o- `        PayloadErrorsFieldName = "errors"# D7 K, l: p- @/ h
    })5 D, R1 |( ]; Z" E
    .AddType&lt;PostType&gt;();4 W3 H% ]/ h: n2 F( k* w
</code></pre>5 M" }. W  q0 J. Z  i% X( ]3 T: U2 t
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
4 Z) Q' i$ y0 H1 L<h2 id="验证">验证</h2>
$ t0 [7 k3 P" A, c7 O6 d5 ^<p>启动<code>Api</code>项目,调用接口:</p>
( {$ X6 C# \; I. f; c' X<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
" U; J' n6 y: R; P<p>终端的日志输出如下:</p>
& l& g2 @; L& z; z<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']
* w2 R7 K  o: A: E: b% ^INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")) l' l6 x( ]/ u+ _7 Z7 X
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);0 M* T/ D- T" i' ]% ]
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
7 V4 w, ?, `2 w8 n: }</code></pre>: v1 S% d1 y; O" R; m) {* p
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>9 r! I) `$ p/ m5 _! x! ]
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>  L! ?7 D- u( E1 S6 h) ~# I' h0 [
<h2 id="总结">总结</h2>
# p3 i% _1 K: x" x" G3 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>' w6 B2 z; W, U( i% u- C0 h* R
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>0 [3 t8 C  e3 H3 [& m0 i. @3 B
# d3 i2 P& S6 G0 H
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2024-11-24 02:59 , Processed in 0.080240 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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