|
|
" }. @7 n7 P% L6 E: `8 g. q<h2 id="系列导航">系列导航</h2>
/ v$ H, ~" V' S$ }7 r0 V$ o<p><a href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
& _8 U3 W5 b1 e# M8 s<h2 id="需求">需求</h2>/ _" }4 E% `) H$ V ~. F; d
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>! J. I# ]# m+ c6 Q7 d9 T# ^
<h2 id="思路">思路</h2>
4 x' H! M: Z+ n; J" v<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
' `- g; i5 x: y ]<h2 id="实现">实现</h2>
4 L$ J3 q. @2 q. J" F! J! _! ~<p>为了保持简单,我们先定义以下两个类型:</p>$ H: X1 B$ M" ?, A6 Z p1 Q# U
<pre><code class="language-c#">// 定义新增Post的参数) w* _. \8 |+ p* j
public record AddPostInput(string Title, string Author);
! ]# Z u3 Q. L/ A+ |6 { v5 e! a- x: ]7 L$ m8 f* Q/ X
// 定义新增Post的返回对象
3 t" D" y, n% V$ j* k6 Ypublic record AddPostPayload(Post Post);
1 i; w9 o* v+ f' u3 i& W9 i* |</code></pre>
: _- B% t7 Q z4 Y<p>新建<code>Mutation.cs</code>用来定义相关接口:</p># A" j* {8 l& c ~ D
<ul>$ W7 V% H! O* a A8 m% m
<li><code>Mutation.cs</code></li>
C$ a- S6 [5 D) @3 p4 T* K% ?0 s3 e0 u- z</ul>" e8 X7 m6 F- r/ H- g! W9 Y
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
$ T, ^' U4 A7 `! `+ ]6 Y
: E. t) Q5 d- s5 b3 Npublic class Mutation7 a$ E( K; V. o& x2 ?" A0 l
{. {$ E: {) v7 R! |; [+ C
public async Task<AddPostPayload> AddPostAsync(AddPostInput input, [Service] IRepository<Post> repository)# L9 I: E- L' q" C5 K7 r
{4 ^! v a: V7 ~7 s6 f: U
return new AddPostPayload(await repository.AddAsync(new Post m& A: } o* G4 z
{: n3 M; k: h+ V- ~3 f: u. \0 H2 H
Title = input.Title,
. Y& V4 e7 x4 n Author = input.Author' I9 L' d$ M5 i8 t* w
}));
H# D9 z X& v! d, t8 j4 | }) e( `) [. B/ R1 D) s) ?1 |
}+ o4 n' X# t# H; k0 [5 D& `
2 B3 r* k" l( t3 }</code></pre> d' b$ v8 r: `- O, t
<p>最后在注入服务的地方进行配置:</p>
' r- U' w* k0 Y$ \" j9 m<ul>8 ^) J: s3 g' L- \
<li><code>ProgramExtensions.cs</code></li>
6 n% E) l" v8 Z$ J/ ~4 |</ul>4 ~7 s% K+ i/ g3 g0 t% e% i" ~
<pre><code class="language-c#">builder.Services
0 Z o6 [ @8 U( g O( ^# ?( ? .AddGraphQLServer()
( l8 w' _, w* v/ L8 ^ .SetPagingOptions(new PagingOptions
3 n- v; F6 g0 B7 W4 W7 n {& o/ g6 B& @9 \
MaxPageSize = 50,
3 H( o; R. m j$ j0 l" Z1 g/ o IncludeTotalCount = true
3 u/ I# D" @) C& I6 G4 h })
4 T. H; v% F/ l B$ s. N .AddFiltering()
% E4 A: K2 e. I, l* ^ .AddProjections()9 V9 v& t8 k( S. a( F4 h. X" t3 K A
.AddSorting()+ n9 d6 u6 X+ ?( H
.AddQueryType<Query>()
6 [: g/ `7 B4 J2 @/ n2 Z .AddMutationType<Mutation>()
1 d" z+ c3 Z d" Y5 g .AddMutationConventions(new MutationConventionOptions
* T: X2 U( Z7 x& k& o$ I {
! a3 t3 X8 |$ {+ c ApplyToAllMutations = true,# ?. g- [* g& K" l
InputArgumentName = "input",1 l* _# u9 l0 e$ ]3 x
InputTypeNamePattern = "{MutationName}Input",
. P. ~0 n3 g" u0 X PayloadTypeNamePattern = "{MutationName}Payload",
6 B' L- G" v- P3 e1 G6 |5 \0 B PayloadErrorTypeNamePattern = "{MutationName}Error",
. T) ?7 M, c- ^) Y PayloadErrorsFieldName = "errors"0 m1 d% M+ c. C/ X2 }* U
})- h) ?9 S8 _2 d! g/ B" N! H
.AddType<PostType>();
& w- I0 `$ b+ N; k7 F4 E! G/ D</code></pre>
! T4 ]: O- _/ S<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>8 w t# C: L# h
<h2 id="验证">验证</h2>/ Z# c( C( I" a
<p>启动<code>Api</code>项目,调用接口:</p>
* Z0 ^4 I, x/ T<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
S+ V f% D# @' _+ {+ K<p>终端的日志输出如下:</p>& o. _7 {- X5 T- B' q/ \8 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']
# m1 c5 W7 p+ ~$ x" L" qINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")2 u5 J# r) O8 R
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
2 r/ @+ W1 X' B w[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'. j! w2 o: g5 q" M# W' h3 |
</code></pre>
* h, X- g) f& W. \2 g<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
* u% o+ u+ r7 j<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>3 W0 M7 U9 T* \) I R( l
<h2 id="总结">总结</h2>
; Y8 e# ?: k* _) _# D<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>+ s0 W6 ]# a1 O% e4 }
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>" q/ i: Z$ d2 a* M+ ^
: X3 L6 n: o& ?4 ~: J1 D
|
|