飞雪团队

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

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

[复制链接]

8030

主题

8118

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26420
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
, m# k0 ]6 T5 d/ ]% C
<h2 id="系列导航">系列导航</h2>: _. u5 [* z: s( B$ s
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>$ j2 g1 O# l9 T7 J' }+ v
<h2 id="需求">需求</h2>8 @2 T6 m, U" j* s+ }6 [9 |
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>- c1 R9 P8 ?4 a
<h2 id="思路">思路</h2>
6 i6 v, ^1 H+ X  O<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>5 T5 J4 h+ j. y& X/ S6 S7 Z# P, z* l+ _
<h2 id="实现">实现</h2>2 U+ S8 x  w+ H  L3 A& h
<p>为了保持简单,我们先定义以下两个类型:</p>
  R# A7 Y0 G0 A. f/ y* }8 l; a<pre><code class="language-c#">// 定义新增Post的参数. U% P' T& G; @" {# ~
public record AddPostInput(string Title, string Author);
2 Z, A# J# m. J$ Q1 d
* l) d3 [- o" d; \5 O& @// 定义新增Post的返回对象( A6 b) W4 V: h' Y5 @* p, J% o0 x! n
public record AddPostPayload(Post Post);
8 Q) Z* U3 O% f</code></pre>  t5 K  t) d& ~$ ~  I( h
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>4 S/ ~' X+ w. g
<ul>5 m2 c2 w* e% v2 P0 g
<li><code>Mutation.cs</code></li>
$ V0 x9 b4 P9 J/ f: H</ul>
! i, ?. Q) G3 B* E% G# L* J1 X<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;3 l+ H: Y) ~# x0 j. Y4 S* s' j' t* D! b

' v, p9 N. d& U) o% _public class Mutation
/ |6 @  S2 I' u- M/ L{
- o6 Y& ^" O8 g7 S1 s3 Z  V    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
. l( G" X8 c+ k. C) Q; r$ S    {8 D0 A7 j& \- {* G1 M
        return new AddPostPayload(await repository.AddAsync(new Post0 Q0 Z  {7 G4 e) a. X( L
        {
' J( E" s! A- T* v; k4 t7 s            Title = input.Title,
6 c" X% E4 J$ }& f            Author = input.Author" n  P' i3 V4 o  l8 _8 z. ^0 b$ f! V. b
        }));
. j( A! a5 O- k$ }/ F# p1 m3 z    }8 u. W; |: r9 X/ D/ l. G( g
}
1 I  T3 O+ [2 G' Q4 d
6 d; d) \( o- e</code></pre>& r; d8 @* u6 S: O. `$ Y8 \5 A5 r
<p>最后在注入服务的地方进行配置:</p>
0 ?. Z, ~, V0 N% N7 A' S3 Q1 H<ul>1 K6 f. H+ Z+ U; V/ i
<li><code>ProgramExtensions.cs</code></li>
8 K  _; @' k1 v/ E</ul>
' K% m4 m# B* N<pre><code class="language-c#">builder.Services. M, `4 X$ V& W# @
    .AddGraphQLServer()/ ?1 a- c4 @5 q4 P
    .SetPagingOptions(new PagingOptions
1 C, {5 h  x& G+ O    {
! ~4 x. m; r6 y' X# X9 x        MaxPageSize = 50,- Q: w+ h& |% D/ e3 J7 w
        IncludeTotalCount = true8 I; o7 r. {  b2 D6 H3 b3 w6 ^
    })
' T  W7 p5 E( ]6 Q% |: a9 w3 k3 H4 M    .AddFiltering(); S: z  w5 h$ a8 I& M& _
    .AddProjections()! ?; K0 \% R3 g2 ]
    .AddSorting()
7 L6 z; G4 w; L; `% e1 }    .AddQueryType&lt;Query&gt;()4 B! W3 l0 P- I6 S, ~& m! \
    .AddMutationType&lt;Mutation&gt;()
5 i1 @+ Q7 C3 x9 H7 M    .AddMutationConventions(new MutationConventionOptions! F- M" e' e3 W$ b( \0 I+ `, A6 w
    {* j$ B" }  _3 c- F
        ApplyToAllMutations = true,, }5 W: G( g# n' W% l% O
        InputArgumentName = "input",3 B) M' |+ b, G& m( M2 e2 X$ T7 e
        InputTypeNamePattern = "{MutationName}Input",
0 |0 D$ v- z+ t        PayloadTypeNamePattern = "{MutationName}Payload",
& ~& Y, [6 O" ?2 W; `+ t        PayloadErrorTypeNamePattern = "{MutationName}Error",7 s2 c- C" q6 B) N7 c9 O
        PayloadErrorsFieldName = "errors"8 f! O% D& Y, G  k" I
    })
2 M2 V# b" [0 p* h* t6 A    .AddType&lt;PostType&gt;();
  {8 w% g* ^! s. t2 `" ?</code></pre>4 Z* e; S. C1 e- F2 M/ T( F) l5 @! _
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
- j4 H% k0 v9 W2 _5 e<h2 id="验证">验证</h2>: B7 _$ y2 k2 B$ k7 r7 g
<p>启动<code>Api</code>项目,调用接口:</p>
0 a4 D) `1 O. Y; y6 P6 H8 U<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
& D! [* K# s! X& ^$ w<p>终端的日志输出如下:</p>! B2 _* c# }+ t7 S, y5 v/ w8 S
<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']0 z. `" O" U9 \) E( A
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
, [) U* n; F+ A1 }9 OVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
* C& s- X+ ]2 X% y9 o& n+ F[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
3 g$ Y0 t" z# V0 O0 J, q</code></pre>
$ z& u3 o2 Y7 k2 g<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>8 g- e# E2 J. H  j
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>6 f7 i* X* a5 A" d+ K
<h2 id="总结">总结</h2>4 |9 U5 y9 V4 C2 ?5 }
<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>
" P# W/ O; z* G& s, G, M3 ]<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
- H* A2 u& r4 \$ G
6 B& h6 t& A. D3 L& k
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-3 02:27 , Processed in 0.064831 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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