飞雪团队

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

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

[复制链接]

7995

主题

8083

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26315
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
! Z3 J2 ]) T! z" A
<h2 id="系列导航">系列导航</h2>
# _$ Y- D0 r9 z4 J& c/ b4 F  Y2 X<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>; x+ |% d$ i: B' r  g/ W
<h2 id="需求">需求</h2>, z; l) ^+ K6 f2 r+ O
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
3 V) n- j: U- v" W3 ?8 f, u! f, a<h2 id="思路">思路</h2>
) P3 m: J1 j3 ]% m- s<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>. j7 [% k. E/ @- D, K
<h2 id="实现">实现</h2>8 z7 a5 B7 r- O- |( ?" }+ T
<p>为了保持简单,我们先定义以下两个类型:</p>
) P5 q$ q8 S/ m# C& D<pre><code class="language-c#">// 定义新增Post的参数
. u) f. j/ O3 Y! B2 M8 Qpublic record AddPostInput(string Title, string Author);% V; A# c6 ], E
( Y  f( c1 _+ u" k$ q
// 定义新增Post的返回对象
3 T8 ]: X" p/ N0 j- j1 ?3 dpublic record AddPostPayload(Post Post);7 M& y9 u. R) h) r
</code></pre>
6 I& H0 [3 a' U<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>& n; q3 \- ~- b4 V
<ul>3 j2 R2 l9 w1 }+ O7 l( d
<li><code>Mutation.cs</code></li>. l( v/ W* A( `7 F# t' }/ H* o
</ul>
8 c' e3 \5 V- L/ Z& b" |<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
( k( n+ {7 L* u) {; x5 M$ x
+ X' I* `# G6 Rpublic class Mutation' e  ?6 ]/ _; t/ [
{
  R, u# y; a4 i, K- R! b8 K    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
7 E7 O* F( I! l$ [+ ~( m8 O$ I    {- e# h; V5 ~2 A# G  q5 @! H
        return new AddPostPayload(await repository.AddAsync(new Post, \" {- T4 `7 r1 U6 Z9 T! u
        {; g' b, H6 e) a! v! G
            Title = input.Title,
% m# _$ O7 P# c4 T8 e8 \: v* o  n2 l8 i; U            Author = input.Author
0 m0 X5 A, l3 R* W! m        }));7 H. P9 {. H8 y
    }
( h  `1 \- Q" }& v# G9 |}
0 l9 A8 j( a+ x3 w* M$ n$ a1 x* B( \' A2 E# X
</code></pre>% l6 I  v7 o: u. ?) A
<p>最后在注入服务的地方进行配置:</p>, n, N' p$ r9 a. z
<ul>
+ B8 j- M( M9 D<li><code>ProgramExtensions.cs</code></li>
7 n+ C' b* D& {; ~</ul>8 n, Y+ a- Q3 C* |! q2 Q8 D7 Y
<pre><code class="language-c#">builder.Services
; t/ `, t: F' A/ x, J) t* Z& P    .AddGraphQLServer()
* N4 |0 h6 z" l7 p1 c# I    .SetPagingOptions(new PagingOptions
( {, j! e5 ?+ k0 S2 i* s8 d% ^6 `3 v" o    {& x8 U/ x; \& ^9 n% F& T
        MaxPageSize = 50,8 d2 `7 ~  l0 I" M
        IncludeTotalCount = true
3 G' t4 A) m% W; s3 p* G. b4 W; G: r    })
0 r# V  O7 I5 v3 A' B: Q    .AddFiltering()
) [' X+ n4 q5 Z$ D- y) Q8 s    .AddProjections()
/ d4 @% S/ r1 l" g  L' G    .AddSorting()- }8 w' F: z" Q5 T7 X; u- [
    .AddQueryType&lt;Query&gt;()0 N% x8 C1 G& V+ y( {% g8 I" j
    .AddMutationType&lt;Mutation&gt;()
: f: S0 v# b0 N2 N* X) c    .AddMutationConventions(new MutationConventionOptions
* w5 `( \. e% a' [6 s    {
, X+ X: c  Y' ?5 B        ApplyToAllMutations = true,& a! m5 a5 x$ h) e
        InputArgumentName = "input",
0 U0 K7 X) O6 j) _, B- x5 Z5 N; [# g, M        InputTypeNamePattern = "{MutationName}Input",+ @  {8 `5 W$ |/ _! P6 M. h2 G2 U. I
        PayloadTypeNamePattern = "{MutationName}Payload",$ e3 y8 s! m7 [
        PayloadErrorTypeNamePattern = "{MutationName}Error",- z  n1 x. [. E! G& j7 g  |: C
        PayloadErrorsFieldName = "errors"
: ~$ X, ~) l4 w7 B# y    })
2 {( O+ l$ p8 @; C8 X/ {; n    .AddType&lt;PostType&gt;();
) J* W% B1 S: J- h& ^) r, q</code></pre>
7 P  h! L- C0 `) M<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
8 R! B* h$ x2 z# I3 Q7 M" a  F2 i<h2 id="验证">验证</h2>2 H9 e, J: p) R8 v; \1 e
<p>启动<code>Api</code>项目,调用接口:</p>. d, r. p- ?) y  ]% V
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>  c/ z) E! `1 M: D
<p>终端的日志输出如下:</p>$ [$ P  }1 ]5 G  D' V2 A7 j
<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']; l9 i8 h5 B! K3 N( X% \
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
5 t1 }' n7 S6 ^9 O' Y8 q  dVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);' p; ?# w- v+ z' a# U
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'; x* V  U2 O3 _! i2 h
</code></pre>, ^  r! n0 x$ n
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
* V0 ]7 E* T& e. u. W8 a! j2 Q<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
( R& q5 W! T, {9 P6 c- ^<h2 id="总结">总结</h2>
, o- e4 V5 t# U# r& V. 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>
" O" C* Z2 f+ Z2 p+ l0 K2 O4 r- g<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>2 {$ b; w4 O0 G* A- ^
0 q$ b; s! }# K
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-30 19:53 , Processed in 0.071640 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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