|
|
" E8 `5 R% J/ F; j% m" D$ E# z; t<h2 id="系列导航">系列导航</h2>) r* S. O0 y- x+ {
<p><a href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
+ h) h) {1 d) a' w# B, P! F: p<h2 id="需求">需求</h2>
' p1 {& p* S8 A! a9 j<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>) [9 h+ @, ~3 U, i( V% m# h
<h2 id="思路">思路</h2>6 l; Y& i5 \8 A) J" I' s
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
, G. A: J: P4 o: _: _, X9 B/ k* L<h2 id="实现">实现</h2>
% p) S7 m1 e4 H8 I5 g# n<p>为了保持简单,我们先定义以下两个类型:</p>: R) m' Y8 |% g8 d' ~! H k ]
<pre><code class="language-c#">// 定义新增Post的参数
' W0 Z) k9 R; C- t4 Epublic record AddPostInput(string Title, string Author);
, b# z9 x. y9 J6 Q. p- y5 ]) |' K9 ?
// 定义新增Post的返回对象
$ j1 E5 C6 `) n, apublic record AddPostPayload(Post Post);
) `; \6 f. w+ | L</code></pre>! a8 k8 w- ?7 @/ `
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>9 D$ U- Q5 N+ X# O7 h! b
<ul>
; W. e9 n! j* V' b8 w- w+ `; t+ H- u<li><code>Mutation.cs</code></li>
" a8 r. E/ B+ {, Z( T# Y</ul>
6 y; n# @' H- [$ t3 }7 E<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;: a) o2 j3 W/ |
4 O5 s$ h1 n/ }6 x# {$ u
public class Mutation) l" r: H1 O9 s! k
{5 X6 d" q% }6 l6 l' R. R( i+ K( h* s
public async Task<AddPostPayload> AddPostAsync(AddPostInput input, [Service] IRepository<Post> repository), ~2 X) S: p3 N' f4 l, Z
{3 O% Q; g2 e- I3 K; u- h3 [, j
return new AddPostPayload(await repository.AddAsync(new Post
- a! W$ m7 }9 R; H {/ C5 p: `3 I b5 A# s% I
Title = input.Title,
7 @+ L- e( E: m" O Author = input.Author6 ~4 J. @. O* _' A$ E
}));
+ d: [& z( `- n" Y' v }
@, K8 m) V' t}
/ ]/ i) e, y, e& I; E( m) p/ B0 k6 u8 e- {% Q/ @: F# m1 c
</code></pre>
# P. s3 ^8 e, H8 ?3 S/ {<p>最后在注入服务的地方进行配置:</p>9 v* a/ _2 Y- |4 H/ [/ h/ V
<ul>; u! O& C! Q/ Q. n6 F
<li><code>ProgramExtensions.cs</code></li>
! Z6 M; F8 q% X</ul>
3 l2 y3 d- q9 B; J<pre><code class="language-c#">builder.Services3 H7 z$ A, b# a2 G% X3 p/ w4 A& q
.AddGraphQLServer()/ P' [$ {8 k3 \0 L; D* A% W
.SetPagingOptions(new PagingOptions! Z5 c7 x9 u& m- I+ V- g* }% m
{
5 b1 s1 {6 J+ a MaxPageSize = 50,
8 M' G! K# c8 V7 \ IncludeTotalCount = true
; y# Y2 \2 c! n6 v% C2 D })3 n6 n7 P5 x, G1 g, L) q9 n
.AddFiltering()4 k+ p4 p5 z4 t! m1 z* d( s
.AddProjections()
8 @( R& F! B: Y; U T* u .AddSorting()2 k: ^4 M" c( Y. Z7 ^
.AddQueryType<Query>()# Y% \' M$ u: e
.AddMutationType<Mutation>()0 Q( B$ h# }" g) N; S ^
.AddMutationConventions(new MutationConventionOptions, H& X6 I& P9 m
{
% O6 w/ p* e. T2 L ApplyToAllMutations = true,
& F; x5 W& u& x9 m# }+ Z7 [ c+ Z! k InputArgumentName = "input",7 \5 y b1 L1 ^( Y( U& z# H/ H
InputTypeNamePattern = "{MutationName}Input",( X- C3 C! X7 D0 `0 V, B' r
PayloadTypeNamePattern = "{MutationName}Payload",
( Q' s" T4 F- d PayloadErrorTypeNamePattern = "{MutationName}Error",6 x2 e a% B% N) q. }
PayloadErrorsFieldName = "errors"
6 ?* r* i6 Q- I3 Q0 D) x O })
7 j/ _( |2 }# p; N .AddType<PostType>();6 h+ G$ x" D1 x$ @! b( d
</code></pre>
* _- Z0 K0 x9 ~ @7 K; \<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>* ?# T1 A5 F7 x
<h2 id="验证">验证</h2>
6 f* r5 ~, D% ?8 \<p>启动<code>Api</code>项目,调用接口:</p>6 i4 M, a1 e; d$ g( h! y7 H3 [
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>/ p- H5 x; [- m: d* p2 x
<p>终端的日志输出如下:</p>7 |* d6 _( O5 g( Y- I" A" l
<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']
- I! h! g" i1 B/ z. r- Z1 SINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")" I) W# {: x5 t% I' {1 P
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
3 X6 }! J, w( Q W. H( |" H[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'# t2 _1 f$ F. D4 F
</code></pre>
4 @7 n/ k# l$ P4 O& Y<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>2 \1 o7 g* A1 l4 [( H7 F- ^# A
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>, x H4 }; Q! X
<h2 id="总结">总结</h2>$ h% f0 Q/ K1 X8 P5 M, Z/ 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>
. |( B2 Q* Q% ~% r5 o T% X<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>4 y0 `7 n) ?6 y) c1 [# W
1 G6 @7 j8 i8 a2 e4 B7 [: b
|
|