|
|
0 ^! G$ L# Q" |) l<h2 id="系列导航">系列导航</h2>
" p0 C8 y4 l; u% v# D<p><a href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>2 d5 m) v5 b$ ~) \$ J( U
<h2 id="需求">需求</h2>
5 T; i3 C& r( I, Q6 _<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
1 d: O, ]$ c, ]9 ~: A% g/ `/ [<h2 id="思路">思路</h2>9 T n) U" k; ~! ?: f4 O
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
# ~& y4 ]" A# x- I T) }<h2 id="实现">实现</h2>
6 o( x- h# r9 {! R; u<p>为了保持简单,我们先定义以下两个类型:</p>! d7 y3 [; x. k# i: @6 u
<pre><code class="language-c#">// 定义新增Post的参数
2 o% ]3 g% u$ S7 ?% i+ c1 c2 Mpublic record AddPostInput(string Title, string Author);. n* w9 q0 W& k+ ^
/ n+ e4 Y2 j- T9 G; l, R' J
// 定义新增Post的返回对象& q: H0 E$ j, |
public record AddPostPayload(Post Post);, w* k( _2 h2 h
</code></pre>+ S: H" a' v" E k9 k
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>" y# o; M! |; X/ ]) |6 K! ]+ c ^
<ul>
) n) f) m% V3 ]- I9 S) Z<li><code>Mutation.cs</code></li>
) r! ^! ?! v% {% y; N+ Z) V! Y8 N</ul>
& o. c; H: i* X* l: L t- Q1 c<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
: [( T1 L" [- \" m4 e* y! Y$ s
- S2 o R+ i% Z& T7 ipublic class Mutation( m3 l9 q* F# k
{
8 n3 }" N9 p) X; m, w: t. Y! ]- F public async Task<AddPostPayload> AddPostAsync(AddPostInput input, [Service] IRepository<Post> repository)
( k: t3 Z! C* j8 |) @7 h$ S3 O {& [! T* \% M$ K: _
return new AddPostPayload(await repository.AddAsync(new Post3 S0 G/ g4 B% `1 R" O
{7 e7 s% u# s, ?+ p$ H9 a, a
Title = input.Title,9 T8 ~+ \. r& [+ k4 h
Author = input.Author9 a) W% S+ i/ i. O1 S4 W/ I
}));* K) C- c+ [( P' m
}9 ?. @2 z' K5 V6 |7 Y
}* A$ R8 _: X6 e; [ A( o
2 L4 T5 B' [- U9 F
</code></pre>
# H; X/ x d2 k% U/ C( }, ]" y<p>最后在注入服务的地方进行配置:</p>' {: n+ n# E! I' {, P
<ul>
& M7 Z3 C% U1 d; y9 s; g; B& e) w<li><code>ProgramExtensions.cs</code></li>
$ p7 E! X6 `' U+ b2 J3 h</ul>8 {( L4 K* X+ j8 i; z
<pre><code class="language-c#">builder.Services
5 o& Z0 P4 C; \" t6 \ .AddGraphQLServer()/ W& \- Y" [4 Q; G+ M. q& f
.SetPagingOptions(new PagingOptions' w0 @% f( r, C
{% q9 u9 ]8 P( t
MaxPageSize = 50,0 k1 H% O2 c2 R1 j
IncludeTotalCount = true( I0 \* d x0 U) `5 k: ~2 O- W
})
4 t0 z. P7 y% K/ U, f .AddFiltering()
7 P. i2 a: R u% @; B .AddProjections()# m& Z4 |! R0 [) L! ]0 q) I8 ~: f
.AddSorting()
& p: m9 B# G1 z .AddQueryType<Query>()
0 Y: A: ]( L9 D0 G U" o" H( W .AddMutationType<Mutation>()
( Q7 C) Q9 L6 k .AddMutationConventions(new MutationConventionOptions
, J9 P! A U9 M3 ` {% @9 L8 w4 n/ W" B) d
ApplyToAllMutations = true,+ F) `9 m6 H& v$ F" U
InputArgumentName = "input",
' l8 f7 i8 b3 Y InputTypeNamePattern = "{MutationName}Input",% Z. P! c( F. b
PayloadTypeNamePattern = "{MutationName}Payload",
+ E# S8 _( z- f' D PayloadErrorTypeNamePattern = "{MutationName}Error",
3 ?3 W- I4 s+ v/ E8 k5 j PayloadErrorsFieldName = "errors"1 Q: H% g# K+ O% E
})* e) L5 g) B# n+ z- b3 r
.AddType<PostType>();& h! k$ Q) z, q* p
</code></pre>
3 i6 N) w, v( n9 U& b<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>4 Y. R! y. `% A9 G; U# z
<h2 id="验证">验证</h2>
% l m2 p6 N$ I, C9 Y3 @8 L<p>启动<code>Api</code>项目,调用接口:</p>+ d/ l- v: v W/ J; f% C2 l
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
]# G4 S/ a$ W+ p<p>终端的日志输出如下:</p>4 T- K' h: ?* u6 `! h
<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'], o% N* Y* }+ t0 i. P- B
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
' N; \& |( F2 H/ U4 ]# _! pVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);' m4 e* O2 \9 D% a% l8 M3 M M' ]
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'+ r6 M, G4 |2 ]; E, ^
</code></pre>
6 w0 m( |2 @% C& J# d<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>. c# G6 o* ?# z% [# {
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
9 P9 E) {2 a8 a$ h<h2 id="总结">总结</h2>
! V U. i+ Z* h9 z1 n+ r4 ]. P, P5 ^<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>
* O% K2 F* L- p) g<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
& i3 ?$ _. C0 T. X- N7 Y6 c3 v8 h1 Q% C) J2 h: f
|
|