|
|
/ K2 |* N( p% h. x8 s<h2 id="系列导航">系列导航</h2>
! s; J/ R5 M& s# k- |& g! h9 }<p><a href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
+ }) M' ~7 e' K<h2 id="需求">需求</h2>
$ L+ R9 c0 _) l* N+ l. v<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
+ ]% k# @( @5 B3 J( E; _" B o<h2 id="思路">思路</h2>, K+ J& i- A/ F0 r4 S
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
k/ C4 G0 N r% j1 F# _<h2 id="实现">实现</h2>" h/ M- P. R, m2 I+ J3 h
<p>为了保持简单,我们先定义以下两个类型:</p>1 I% v- t5 Z" B3 X4 X3 J
<pre><code class="language-c#">// 定义新增Post的参数9 D3 T$ r4 J2 a
public record AddPostInput(string Title, string Author);5 l' m2 U/ ?8 `3 l
, I: b. Y% G. s$ B8 P) W2 t6 f// 定义新增Post的返回对象
, u$ ~! m( ~2 _2 ^public record AddPostPayload(Post Post);
! b8 t3 z' u7 l& d0 F$ U1 p</code></pre>
W, j1 a, m9 _1 x3 j9 P<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
5 y" ~. Y* O# J7 z5 V! x! C7 {<ul>
% Q! T; s( g( X9 D2 y7 g, F$ q<li><code>Mutation.cs</code></li>6 q& B3 v0 q% d* l. U7 q, }4 G& |
</ul>" O1 y9 `# {( x- b! d! z
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
, m6 y6 v, a0 C! A* y; }
- M, v' D% Q& j/ @public class Mutation
! O; Y" d. ?2 d" \3 }& v0 m{
$ {8 o) }8 O9 Y4 K3 z8 F( ^* [1 r public async Task<AddPostPayload> AddPostAsync(AddPostInput input, [Service] IRepository<Post> repository)
8 w% u% `: p) U8 Y& d {8 m: `$ ~6 @5 c2 j V
return new AddPostPayload(await repository.AddAsync(new Post; M5 J, N8 ?9 h2 ?
{- w5 \( Y* X0 G9 x
Title = input.Title,
- S" t9 Y4 c" @6 Q( G0 F, L Author = input.Author
. S- B: g2 s$ N6 D6 x( J }));
9 b$ d& a# p8 o* E' j }
+ M" ~4 e3 z( a( y% Y}0 U7 q( ?6 i) G& _1 B% p
4 c P( E: n( }: ?# @
</code></pre>3 o9 X' b( r8 v1 A
<p>最后在注入服务的地方进行配置:</p>
: M; O$ c$ d. t+ V4 h<ul>
. \ _/ h+ \$ }; F1 E+ e<li><code>ProgramExtensions.cs</code></li>1 ]$ m# `9 [, k0 z2 B' a, @
</ul>( e2 q/ S, ^! I7 A5 X, F' m
<pre><code class="language-c#">builder.Services
! K9 l4 U2 g( a0 `* ^* g( ? .AddGraphQLServer()
6 \! @8 K: T" j, Q3 X+ D# | .SetPagingOptions(new PagingOptions8 A' I2 g) P% V
{
8 c' u8 s) L" P1 j MaxPageSize = 50,
n+ V# Q+ n% X' `0 p1 T IncludeTotalCount = true3 p0 N1 X* h4 n% \
})$ K g" b$ s1 ]0 g5 a
.AddFiltering()
$ Z* `0 t5 `5 E' b .AddProjections()
7 }6 t* { b8 e1 P .AddSorting()& W) M& \8 m n C) w- u4 q R; F; O
.AddQueryType<Query>()$ C9 D+ `8 B1 N/ A
.AddMutationType<Mutation>() E9 n0 D2 \# C$ j3 n5 p3 D
.AddMutationConventions(new MutationConventionOptions
e/ S8 x9 C. E {
% Z: N( }4 Z( }4 h! o# k2 Y ApplyToAllMutations = true,- M1 x- P1 c) A3 _
InputArgumentName = "input",
5 S$ u1 W; S% Q# X9 d: I' P InputTypeNamePattern = "{MutationName}Input",
; \9 \5 m0 e0 ]9 I! P7 b PayloadTypeNamePattern = "{MutationName}Payload",
1 W5 X5 v# O( I2 K PayloadErrorTypeNamePattern = "{MutationName}Error",
# }; s9 S0 F; {' H# z% B PayloadErrorsFieldName = "errors"' G% c1 @7 U& k* n, G( L' E
})
7 [8 M2 T- Z0 N5 Q3 H+ `, S .AddType<PostType>();
/ }( J+ K3 i) c$ }7 g) ?( m</code></pre>
' j' I( H* a, A$ K+ \<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
! u( v D/ [; k+ @0 E6 t<h2 id="验证">验证</h2>
6 b/ O2 s" ^7 g3 z4 q- }- ^<p>启动<code>Api</code>项目,调用接口:</p>9 S1 X7 w" f; r8 G% s
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>, {. ] u6 u3 D& e! F& @( e8 n
<p>终端的日志输出如下:</p>
$ @+ Z# u+ m: r. 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']
% P$ b9 p, v& u7 dINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
9 b6 Q3 s$ y% w) sVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);# o6 T4 `: d- A4 Y+ ^ |2 T
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
+ g& ^4 J- I2 n# t X9 K, X; s</code></pre>
! D5 l2 R8 K4 S7 \. I& c& b<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
0 Q" M% X3 G8 N3 ^) y( r<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>! J' x$ _$ O, P
<h2 id="总结">总结</h2>/ O, F; M2 b- O) C7 w$ i
<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>3 L9 X0 c0 Y+ k2 R, n# P4 W) D' ~7 `
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>% d, y3 B/ `$ G) h; V1 X. B$ A
+ C) S- J u9 Q/ w$ e- P+ q7 R; m
|
|