|
|
- ]3 `7 M1 p. E' ^<h2 id="系列导航">系列导航</h2>7 k1 r/ u) X! |# M8 |
<p><a href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>) K2 b x$ M. _1 f$ [+ ~' W
<h2 id="需求">需求</h2>
# ?* L! u5 W! K/ N<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
/ D" F P$ t- c0 W* a3 n: V<h2 id="思路">思路</h2>
+ W, P. d7 k' C# U! M<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
; j* e0 @' w* N! F4 Q( _<h2 id="实现">实现</h2>4 `( i$ Q4 e& _* `% t( x
<p>为了保持简单,我们先定义以下两个类型:</p>
( e! u7 d' Z5 C( g2 n; f, k<pre><code class="language-c#">// 定义新增Post的参数
% v* Y* W8 e% J' ~& f4 E8 Qpublic record AddPostInput(string Title, string Author);2 T+ `' V; c! D( H+ P$ H
0 u) V1 H7 s+ n4 \2 Y4 b9 V+ ]! N
// 定义新增Post的返回对象
, s) A/ z2 v/ S y0 `& Z. kpublic record AddPostPayload(Post Post);& I' O8 q4 G( r$ F
</code></pre>
& ]9 i% }: k% J5 O<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
* I4 Q S4 [1 U" }# T- F<ul>
" \; u a2 {9 [6 v<li><code>Mutation.cs</code></li>& y0 t p4 H, s7 m, r
</ul>
. K+ t5 ^3 ]1 d<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;3 ^4 y! j3 m& b6 K# q
- v9 O5 Q) q+ ?7 v2 R8 U. W9 x* w
public class Mutation
# S3 E ?8 A/ e1 {: z{0 e9 ^# ~0 k6 m" E6 N6 t0 k
public async Task<AddPostPayload> AddPostAsync(AddPostInput input, [Service] IRepository<Post> repository)
J& Y! a5 w' }9 K% T# _ {5 @, M$ U9 D5 p
return new AddPostPayload(await repository.AddAsync(new Post S- {. L! o' [; v! }
{8 ], {- \/ Z6 ]8 _
Title = input.Title,3 p* ?! P9 M$ \
Author = input.Author
7 @! b3 z8 x# j* n0 ^ }));
/ ]" h6 m/ K8 Q( g9 }6 m, J }/ I2 M9 l# s: |( V% p) Z) O% W
}2 W# q8 Y9 O2 h ^5 U. Q
; [3 x {/ Q+ ^ D# l& M& E( o</code></pre>
8 h H! A+ p& U; S; ?8 Q<p>最后在注入服务的地方进行配置:</p>/ d* o0 L. G' f/ n; \* H
<ul>
- P( `1 H1 N/ ?<li><code>ProgramExtensions.cs</code></li>5 l4 T" K( {1 K- {8 w1 |; g: B; h
</ul>
7 @: T& Q. ]7 O. @8 Y2 m<pre><code class="language-c#">builder.Services2 r0 c/ T, O! U n
.AddGraphQLServer()1 A4 j; ]# b: q3 B/ A
.SetPagingOptions(new PagingOptions
3 z' H+ C# D+ C3 y9 J" r7 v { b+ {) M; t$ A f& j& t# V& g4 }
MaxPageSize = 50,/ e+ M, {8 Q% q4 Y# ^5 h
IncludeTotalCount = true
8 a0 }+ u f! T I })( e, n3 T( u+ N% ~
.AddFiltering()
# B9 X; F: x, o/ k .AddProjections()$ s9 O& x4 t8 f' ]' d
.AddSorting()% h; S+ D$ h9 ]
.AddQueryType<Query>()
9 }+ ~/ @& i2 ] .AddMutationType<Mutation>()
5 o/ T/ @% b' v. P' T& y .AddMutationConventions(new MutationConventionOptions, z( ^' N5 f ?$ _/ Y
{
% m2 V: q+ m) ^/ C$ Z ApplyToAllMutations = true,
! G. b# |+ {4 W2 G, m4 U) H InputArgumentName = "input",2 R4 a% |* G4 }: f4 E( K. w
InputTypeNamePattern = "{MutationName}Input",
, }) t" b9 d W( c/ G* A9 B PayloadTypeNamePattern = "{MutationName}Payload",4 z# b5 g- S% e9 K/ c
PayloadErrorTypeNamePattern = "{MutationName}Error",' a( o0 N! U5 @3 E
PayloadErrorsFieldName = "errors"6 g4 z, [" i7 k% q; o
})( S3 ]4 c/ y/ x# p+ a+ i5 B! _
.AddType<PostType>();
6 C! p6 h4 }0 g4 I$ z</code></pre>! p% u5 ^7 R4 [: U$ [
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
: ?6 W* j0 R3 u& Z& w' x<h2 id="验证">验证</h2>
' w2 J3 @' r7 P8 s<p>启动<code>Api</code>项目,调用接口:</p>
0 g z F, Q0 s" b0 ^4 e7 P6 J<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
2 ]. L' [9 _; i6 i<p>终端的日志输出如下:</p>
5 M* i4 D* @9 A! Q) u<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']7 F0 {' N+ M2 b4 L
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
/ ^ }4 f: }; L( rVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);/ k: E% D# `0 H8 [- e
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'0 d0 e @7 t( [; m
</code></pre>
P" E- V4 D4 o# M<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
2 g* q4 h- Q+ y<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
$ ~% I" l( l. @- s% p1 r<h2 id="总结">总结</h2>
$ B& ]+ y J" o2 H8 T/ l6 Z, ^<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>
7 E* g8 K! S u+ a! H3 l<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
* S& V1 B: J1 ~! F, y# I& P; }- G& J, v2 `# t" |
|
|