飞雪团队

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

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

[复制链接]

4822

主题

4910

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

) m7 }: U+ o1 s' R<h2 id="系列导航">系列导航</h2>
: n' }7 e& a7 \; N% M1 ?<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p># b, {$ z) p! M4 w& D8 f' y; @. W7 V
<h2 id="需求">需求</h2>. S* _1 k4 l" i& _8 |
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>7 u: E/ ]3 a& U4 l7 g3 ^: M! Z
<h2 id="思路">思路</h2>
7 q9 L, e  l& y<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>" v2 Q% X& H1 ^+ E$ ~8 x9 o: |
<h2 id="实现">实现</h2>) o- z6 Q9 W1 x- s8 C
<p>为了保持简单,我们先定义以下两个类型:</p>$ ]) q1 _3 e" U" c
<pre><code class="language-c#">// 定义新增Post的参数
& T/ G( V1 `) Z6 d# y$ D# Mpublic record AddPostInput(string Title, string Author);5 D7 o* b# N) X0 ~) R6 f

1 ~# b3 O- @; S// 定义新增Post的返回对象
( _4 Y+ y1 ^. [7 K3 |7 t! r1 fpublic record AddPostPayload(Post Post);8 g. K7 R7 P8 j: c' V# p
</code></pre>3 \" ^# j$ ?# {7 E( E" G7 P
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>5 U4 F* W% N# o2 z9 J  {( H
<ul>
6 F, j, o) b  D3 ?<li><code>Mutation.cs</code></li>
. R2 X) k) o; ^+ t! _* {, ]</ul>
  |; D( S( r0 p* x6 j<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
  D$ b% |- U7 ~! M3 N8 S3 \1 r" c. ?' C$ v) ~5 M
public class Mutation
: I. b* j$ B, `, Z  Z{) N' W/ O' Y! i0 ]. b9 {  L3 @' q+ G
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)9 A# c0 g; j' R; v0 U! ]/ F
    {& K; u* B9 W6 k. ]& ~9 }
        return new AddPostPayload(await repository.AddAsync(new Post
& Z% }, ?/ ?' I* v* m" J        {" }9 |- Q4 q' ?% U5 B7 i3 A# x
            Title = input.Title,
9 X5 `2 e) p. g- l. e3 r            Author = input.Author
# d; t  r& Z! u0 Y, x5 n        }));/ ^! Q4 _) z2 u& b. D  @
    }- K, Q& u2 U6 a' t0 h, C, J
}
/ V4 w# L$ v0 X7 h, j) g+ b( _# z% |. H' e. U
</code></pre>8 T7 L% s/ m& Y1 f( h. G
<p>最后在注入服务的地方进行配置:</p>
/ _, Y: {  V3 [/ h& K& o" H/ x<ul>
" j, h5 P- }+ `2 [, L' i( r4 Q) W$ n<li><code>ProgramExtensions.cs</code></li>
2 W$ m3 c& {& f  u3 I1 y/ u</ul>7 j0 l1 p6 J3 L0 \: A3 D+ E
<pre><code class="language-c#">builder.Services/ H( X- F4 g8 o7 I# w) j( @9 b
    .AddGraphQLServer()
" j$ _& H# J( r: t6 Z    .SetPagingOptions(new PagingOptions
) ?) ~2 M  B3 q: `5 k; U. }) b    {
. U( \: R6 Z% p7 f/ U. O6 h        MaxPageSize = 50,$ u: b/ n, M# V, R9 H& I+ e# F# |
        IncludeTotalCount = true+ Z2 b, r$ A9 ?% m6 h) z4 X
    })
. k% ]+ C2 \8 U  X1 i% f+ i5 ~    .AddFiltering()& m) b: l8 \; e: B7 X" [  ?
    .AddProjections()
, I/ W" X' q. \$ {    .AddSorting()
; h- P* }$ ?& j2 A    .AddQueryType&lt;Query&gt;()
/ [+ T$ h4 @) W, X# z    .AddMutationType&lt;Mutation&gt;()
! e* E- }, `' M/ m( M& n; T    .AddMutationConventions(new MutationConventionOptions
5 v. B: H! Z3 F$ F8 l( H    {
7 J+ ~+ ?1 s, D2 C+ b5 a. Y        ApplyToAllMutations = true,7 ]! l% G6 e8 A) m4 V9 a% `
        InputArgumentName = "input",
( e' y+ e& J9 d" m9 x1 E8 p! [        InputTypeNamePattern = "{MutationName}Input",
  _6 c; i2 E' q% M" o4 {2 h1 ^4 R        PayloadTypeNamePattern = "{MutationName}Payload",7 e4 T7 f! D  y5 z" ?3 a6 c1 y, i
        PayloadErrorTypeNamePattern = "{MutationName}Error",
) R# t* J! Y3 n+ b# ^9 b0 ~        PayloadErrorsFieldName = "errors"
! w7 d3 u$ t( m" \% i+ F  v    })1 G; Y! [- s' H  }
    .AddType&lt;PostType&gt;();
4 J) {9 Y+ o5 N! q* z</code></pre>8 o. y% D- A  u, Z- P  g7 J
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
: ^9 X/ F! h/ s% ~) ^' k# v<h2 id="验证">验证</h2>
2 ^3 i6 m8 X3 j9 o9 M9 m4 \<p>启动<code>Api</code>项目,调用接口:</p>
" D6 K. o" {+ V/ C: F8 t<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>3 K, B7 P8 Q5 K# r* g
<p>终端的日志输出如下:</p>) c- b: q+ b( ?3 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']1 \" l6 E+ Z- b$ o: ?: R
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
7 K3 I* _9 c+ x7 k- M+ r' pVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
* h6 ~9 V5 B/ J% z+ d[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'% m8 O& Q! d. Q& g4 s
</code></pre>
1 c: H+ A% U) U<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
( Y' x5 Q4 k' l5 |1 J<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
1 q; a: D: t7 U- n3 [  V<h2 id="总结">总结</h2>
/ [: s8 |# b( f5 _+ Y3 y4 _' Y<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>
, w3 e4 E) p/ X7 M% _( G<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
2 G& I( ]9 P6 S% k. ~, o! W. Q  x/ ?
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2024-9-20 00:50 , Processed in 0.063661 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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