|
|
6 w7 t- Q$ P6 F<h2 id="系列导航">系列导航</h2>
% w9 n- Z: a8 Z; [; Z U<p><a href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
# F" a8 }! \& `' s$ `<h2 id="需求">需求</h2>
: g8 A1 g6 h) U7 [' W$ T<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
: h5 Z5 }" |+ L u( g0 D<h2 id="思路">思路</h2> E1 O. b# p: A- N6 ]* _0 V
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>" d/ t- P+ c9 J+ L# `
<h2 id="实现">实现</h2>
$ L5 U* r- O( {. E<p>为了保持简单,我们先定义以下两个类型:</p>
; r6 O0 R; k4 D% F<pre><code class="language-c#">// 定义新增Post的参数
9 X& a3 D% C8 o5 ^, \/ ipublic record AddPostInput(string Title, string Author);
( z; X/ R; n4 `7 T2 G& P9 _! W" Q) K5 L- g3 \# q- r
// 定义新增Post的返回对象
; T9 T/ v' Y; N- }. p1 l; W1 _public record AddPostPayload(Post Post);
! A# b! Q' f5 s9 a/ G! r</code></pre>: v9 f, s7 T6 O. m0 m- j
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
0 m, l4 h* w% d6 q% u8 z1 ^<ul>3 h8 a. b8 b0 {( y# I' U3 p/ n
<li><code>Mutation.cs</code></li>
A; u8 z4 @0 J# Y# y" C</ul>/ n1 i3 e' j5 U3 s F" B
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;; L) v5 X. ]2 [2 K, O+ s
) u' @, n; P" w1 N0 |' a+ g+ y
public class Mutation; q' g, {1 V( u- d4 ^
{+ b4 k! q; c$ T3 X$ j3 E
public async Task<AddPostPayload> AddPostAsync(AddPostInput input, [Service] IRepository<Post> repository)( V! W- K$ w- v" k2 [
{& ]! P; @( }- C2 r2 q6 _2 Z
return new AddPostPayload(await repository.AddAsync(new Post$ n( P; H, y! @/ o [7 a
{
; S: ]: N% z9 i* x7 _) V Title = input.Title,0 I' T* O. V4 g( s9 A# j p
Author = input.Author
& F, g8 Y* r% }! x ^ F }));
" g( M7 G7 q2 I0 ?' f }. P3 {4 O1 b" M, N. ~
}
7 i! t) ]& [- P. M& ^
8 G: \: l, V& ^6 @6 j: A0 W</code></pre>
$ e2 X% v+ \ G<p>最后在注入服务的地方进行配置:</p>, g* e0 K: q! E8 C
<ul>- f9 B7 ^# J$ @& D/ C& v
<li><code>ProgramExtensions.cs</code></li>
) g0 l# s7 n& _% S% t</ul>
k T1 `2 Y( R% J }. r" i; J! X8 X<pre><code class="language-c#">builder.Services
" ]- x( N3 H: _7 n. g .AddGraphQLServer()( t6 g$ m" f* t
.SetPagingOptions(new PagingOptions! `, d5 k1 q: ~6 i
{5 f5 d8 _9 ]4 A
MaxPageSize = 50,
, J9 y$ ?+ W+ ~$ \8 K IncludeTotalCount = true7 }3 W7 S2 r b5 f0 F: a
})7 b0 H8 J* g8 L. I! F8 S
.AddFiltering()
# ^2 A ]# ?8 J% S2 y .AddProjections()5 t' \9 {) H7 { t
.AddSorting()9 b8 c2 m4 f2 t9 O& s- O7 y3 W
.AddQueryType<Query>()
- V+ U& D! v% C .AddMutationType<Mutation>(), r2 C, D7 b3 {4 D/ f5 q9 a
.AddMutationConventions(new MutationConventionOptions7 ]! ?& y4 m9 M+ i2 M
{6 n+ V8 C6 q) J% x( ]' m
ApplyToAllMutations = true,$ D) E; R+ H/ m* d4 _5 F$ G
InputArgumentName = "input",, _0 `' c/ }/ S7 H
InputTypeNamePattern = "{MutationName}Input",9 N8 x" h& i! L3 W: j7 [
PayloadTypeNamePattern = "{MutationName}Payload",
+ ]% q( q/ I4 E9 I4 z* k8 U PayloadErrorTypeNamePattern = "{MutationName}Error",
3 P8 L5 _- {% q0 h6 `9 r( `, D PayloadErrorsFieldName = "errors"1 B, M3 S4 b! W. ` ^: m2 K0 w2 L
})' O2 x, ^# y6 C& e# P4 W
.AddType<PostType>();- U1 X2 B0 ]+ W- L- u
</code></pre>
/ m; c/ B9 A8 Z( J: ^: L" X" W<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
8 w3 S% |3 k0 s. K<h2 id="验证">验证</h2>% G' L/ l: m5 ~+ ~- B, {
<p>启动<code>Api</code>项目,调用接口:</p>
9 x Z( D* V9 h! G. Z: e- C8 m9 l<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
0 Q. y* w' T) t, C<p>终端的日志输出如下:</p>0 Y- {- M, A P9 h# l; X7 }
<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']
: _" a: z5 G4 b8 q- YINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")5 G+ p/ ]1 z; v
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);9 r. w9 r2 x& Z4 ^5 W. k0 a: k
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'+ O, ^; R# e4 ]
</code></pre>
# x2 y# V, Z" s" J5 M, o/ N<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
& Z4 \/ Z1 j& K) O5 S) u" e<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
+ Y9 N$ N& I9 i1 y<h2 id="总结">总结</h2>% T1 O/ I* W: l9 c* e# U; ]
<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>6 a7 ?$ m! j3 O& L1 h0 J
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>, m2 F$ f9 p! \( K
6 e( M; x: e8 o
|
|