飞雪团队

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

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

[复制链接]

8042

主题

8130

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26456
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
' b! L5 X. j. U( D7 X) T  {
<h2 id="系列导航">系列导航</h2>
) F: d6 [3 t, N9 r+ G5 A' k' P<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>( A' z) v3 ^+ Z6 f& f
<h2 id="需求">需求</h2>
; ]! t9 L, J9 q) F<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>3 s/ Y7 w2 h" ~9 ?; S
<h2 id="思路">思路</h2>  a# Z/ H1 S( B7 @1 n; Z
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
3 Z1 j' X- @# J0 p# B& \<h2 id="实现">实现</h2>
( ]- w) D$ j# N5 t( H: O<p>为了保持简单,我们先定义以下两个类型:</p>) S' z0 y4 Z- z# \% U
<pre><code class="language-c#">// 定义新增Post的参数
- ?. @, ^8 W' x* E  lpublic record AddPostInput(string Title, string Author);
7 a* Z% A* q9 [, T8 x4 a! v! A1 K3 S' p! [3 X9 W5 ^! s
// 定义新增Post的返回对象
/ w, N: e# h' E, z. C' Kpublic record AddPostPayload(Post Post);6 \" `% i2 b. t( w- ?
</code></pre>2 z, l: S( |. n7 p  m
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>- ^# d/ }) K9 z4 g0 B# C
<ul>' z2 p7 E9 b3 c+ C/ G1 |) A& h4 Q
<li><code>Mutation.cs</code></li>
$ D0 ^5 h, X& F  `1 K8 L% R</ul>
* M  T! A7 s! k& I<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;/ ?  Y  r: ~0 B  b6 w. @  N* ~

6 ~3 x# K# F7 k' \  gpublic class Mutation  d$ \  r8 k! d6 F. H$ r0 m7 b' Y8 p
{8 p. N. }3 o! N- }* c
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
' z3 g. Z/ t: A, M/ p3 F    {
5 [) Z- M, C6 d% v% H; n" Y        return new AddPostPayload(await repository.AddAsync(new Post* g0 w0 \$ K/ i. x
        {
8 \; \  }4 T1 X) U) u3 q0 m# z% @            Title = input.Title,
8 p) o5 m1 W, h5 g/ k            Author = input.Author  G0 s3 c/ h) R$ K- M4 y, H4 \
        }));
( w4 [3 u- q" u# E1 V% O    }+ z* y# \5 y: s) L3 n( |0 H! b
}
4 x# k3 O. G( Q0 Z: d$ j& ]+ N8 @! K. y+ G+ v6 s+ X  U/ O
</code></pre>$ G! r8 Z% L) H" C+ Z& f
<p>最后在注入服务的地方进行配置:</p>3 R: t$ p9 H' d
<ul>! C. F. j! Y: G3 _
<li><code>ProgramExtensions.cs</code></li>, G# `& O9 Y" j  T* |
</ul>
7 W' a0 G) w" B$ s/ @/ P<pre><code class="language-c#">builder.Services
' O3 }% a, _9 Q. o2 F! P    .AddGraphQLServer()
+ r  G% A! j* z+ t, {% ?    .SetPagingOptions(new PagingOptions
. o9 \, {) M9 I( q) J) S) i    {9 P- I3 s0 ?* C& b3 I( y
        MaxPageSize = 50,9 C, h/ G0 m5 o! D3 I0 u. ~
        IncludeTotalCount = true
! d+ ]  |, h: ]; B- g  _' p. [    })
$ c% ]& M- c* `# _& ^    .AddFiltering()
$ t" D  u. H1 B    .AddProjections()9 }0 }7 X- h* H/ C8 E& K$ b2 p
    .AddSorting()
' w: T, h  }9 r. i! x    .AddQueryType&lt;Query&gt;()
2 }  _9 {' N+ `8 P, s; J# w    .AddMutationType&lt;Mutation&gt;()% _5 [" V& L- H& L' B  ], q* @
    .AddMutationConventions(new MutationConventionOptions/ W( \* J- w2 M  |
    {2 {" u3 b4 L1 ^) y. M0 H: r9 {% o
        ApplyToAllMutations = true,
9 L' \% a$ q& y! u        InputArgumentName = "input",+ c# I. E5 h) m+ b, [  ?' K# P. l3 n" Y
        InputTypeNamePattern = "{MutationName}Input",
1 @$ n5 U) Y. v- Y( _- g0 W        PayloadTypeNamePattern = "{MutationName}Payload",) U2 W( W$ c; R
        PayloadErrorTypeNamePattern = "{MutationName}Error",/ P  S# n6 U! L: b
        PayloadErrorsFieldName = "errors"' {7 A* d$ j5 j3 M4 q
    })
" `; [1 z& z7 j# g2 g- G7 h/ R    .AddType&lt;PostType&gt;();
2 p/ }" @9 X* T  M/ n</code></pre>: j( C$ `5 k: W* [" u
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
! y% \, e8 ~$ d" B; d<h2 id="验证">验证</h2>$ H& C% o& g2 N- K3 R, b8 \
<p>启动<code>Api</code>项目,调用接口:</p>* M) ]1 i6 \' |& @) n3 w3 c4 t
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>- M' L) z+ a; x: z5 n; n+ {
<p>终端的日志输出如下:</p>
( v3 Z3 v  i& y, C+ l% F$ C* e% O<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']
( A6 M0 }2 }' {INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
' n6 C1 v( h2 z; ?: p8 E; HVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);- f( b: H# B  x$ W; H) ~
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'" m% ?+ R( i9 p. n' L6 l
</code></pre>3 Z3 L% x, m3 Y; n
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>4 v  M) f& M$ T* I
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>" H4 D" r5 W; t5 p5 Q0 _/ E# E8 m  d
<h2 id="总结">总结</h2>
' i3 n( n. W* f2 D<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>! s) m0 O2 H, E6 G- O$ b# g+ |
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
, s$ q- J9 M  o1 H3 }( g7 p: ?. e
6 j2 u5 ?5 C2 ~% Q) M# N8 ?$ s. Z& o( g
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-7 16:27 , Processed in 0.083181 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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