飞雪团队

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

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

[复制链接]

8053

主题

8141

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

8 J: N% q  P4 v/ E8 }7 I<h2 id="系列导航">系列导航</h2>" A, Z; A" b: O; G
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
4 s& X* H' x; W<h2 id="需求">需求</h2>
0 M  ^4 t: _2 o  J# m  f: k<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
2 u2 N7 D7 ?, G1 \* h$ m! h) {8 C<h2 id="思路">思路</h2>
) [  }: F1 v9 f6 _$ g0 Y& u7 K<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
: q: H" `. M( P6 d& M  i6 C<h2 id="实现">实现</h2>
' i" Z1 Y! W0 E<p>为了保持简单,我们先定义以下两个类型:</p>! x. X7 L  l; f
<pre><code class="language-c#">// 定义新增Post的参数* \# L, c( e1 I7 x- k# k- [3 a
public record AddPostInput(string Title, string Author);! w! M& ^* \( Z: s

; d. R6 q% ^3 `' [$ r! |, z// 定义新增Post的返回对象
8 N4 e% C8 ]# c3 ]& T, f& ?public record AddPostPayload(Post Post);
  b- \0 [+ U* b7 O+ a# q; q</code></pre>$ Z# L9 N/ e. j; M
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>5 s: `+ o. ]5 J4 ?9 V. J: B+ C5 s, e7 Q
<ul>
( P/ l/ R1 c: D, Z  X: c3 d: [<li><code>Mutation.cs</code></li>! s0 g' y- M" g% ]5 ~* H
</ul>$ ~/ v! Z. Z3 |, _) N
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;/ l  z$ S6 ~+ Y2 L  M5 M# q0 e" @

+ C) x5 g3 b$ I" T0 i8 i) \; @% ~4 z4 `public class Mutation
9 _8 P: J: j+ R! x{5 f& l: C8 K9 j7 h  N$ s
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
8 L% M9 }" ], h" t' R6 a    {. h6 W9 S: e( z) Y
        return new AddPostPayload(await repository.AddAsync(new Post
* d5 E3 a, |+ x0 F4 T1 N- ^/ X5 S. \        {9 U( w6 L3 h7 G: \
            Title = input.Title,- P' ^4 _- p+ s8 F7 D
            Author = input.Author
* [# h9 c9 C+ h% B+ a        }));
3 \% G, U6 [$ s5 Z; y    }
9 X3 Y/ K5 V' m9 f8 S0 F}5 `, ^7 Z$ q3 s0 O" E9 e

5 ?* v$ o$ r% q4 [+ D</code></pre>
8 t8 w1 r0 `" l$ H1 X<p>最后在注入服务的地方进行配置:</p>& I2 s( ]9 R+ W/ B, v3 p) V
<ul>
& r0 v% p4 @7 g% A( _<li><code>ProgramExtensions.cs</code></li>- o) X, c, @9 D& O) N
</ul>
, b( u7 n' K4 D<pre><code class="language-c#">builder.Services5 r# q9 s$ }8 x4 U6 P5 O
    .AddGraphQLServer()2 q' Q( N1 z5 W& D' X
    .SetPagingOptions(new PagingOptions$ N1 P# z0 o+ [* n
    {3 y9 p( Z. e$ G
        MaxPageSize = 50,+ u' ?, w% {, d+ X  w9 ~
        IncludeTotalCount = true1 n6 G) w; i9 X9 n; a4 C6 V6 b$ T
    })5 k: l& P; W' R" k
    .AddFiltering()
0 d; B  u* c0 Z    .AddProjections()
% ^5 o4 c# c7 A- L$ X4 J7 q0 s    .AddSorting()
3 T, N3 f& [" l- N' {    .AddQueryType&lt;Query&gt;()
% l3 ?% P2 Q: x% @1 _! w    .AddMutationType&lt;Mutation&gt;()+ \: m) `3 h. f& }* X* n& E# Y
    .AddMutationConventions(new MutationConventionOptions
3 U$ Z3 \9 s$ o$ C9 r) x% ]    {
: N: D" x  @6 w3 X        ApplyToAllMutations = true,1 g( Y! w% J; N8 w% W
        InputArgumentName = "input",
& Q& S$ Z! l$ ?7 i1 w- W        InputTypeNamePattern = "{MutationName}Input",
! e5 g+ y; w# T: o        PayloadTypeNamePattern = "{MutationName}Payload",. n; `3 l8 ~" w7 _, Z" T/ v. ]
        PayloadErrorTypeNamePattern = "{MutationName}Error",9 @# S1 N4 r; J9 w5 S; @! z
        PayloadErrorsFieldName = "errors"
- h* A4 T9 J- |. Y) f    })0 c  A$ H# k" x7 t
    .AddType&lt;PostType&gt;();, u( k6 v% X( y# U2 I5 H$ i
</code></pre>
9 N; {+ j4 Z; q* F<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
/ d3 B( i; ^* A<h2 id="验证">验证</h2>
+ d" |* k( M6 F, o1 o( r5 K<p>启动<code>Api</code>项目,调用接口:</p>- |: ?* t- _; t0 {% l8 E
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>- [  }& V4 B/ s4 s  |4 y0 }/ [
<p>终端的日志输出如下:</p>4 h, ]; x& E+ m; 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']* B0 j4 }  M4 P
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
8 ?8 O5 ^) Q: f8 |8 W2 n, iVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);2 ?, X3 x: i! Q4 C6 |4 _. q
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
+ m+ a+ {5 |0 C  s</code></pre>+ k) g4 S/ \/ r( C& `. [
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>1 s+ W8 j  R( ?& M* R
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
/ N9 m5 i5 X- w( `, ~: e6 o( z/ H<h2 id="总结">总结</h2>
" I6 @/ r6 i  U<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>% q5 \! |+ B+ a7 j
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
0 C/ h# Y3 G7 g
2 s* m7 W$ B& v( a/ ]* @) S. g
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-12 08:20 , Processed in 0.060436 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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