|
|
$ B! |6 {+ \' s1 r8 }
<h2 id="系列导航">系列导航</h2>4 K* o& f+ |3 T! x( a1 w' v8 ]+ ]
<p><a href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
4 L; w- O7 u# B- \ O<h2 id="需求">需求</h2>9 K; e/ v) Z: s7 A4 y5 Z
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>5 J# q* P' i3 u1 V' l
<h2 id="思路">思路</h2>1 X$ U: p2 R) Z# [
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
+ a: L1 P4 C5 P& a h7 m1 p- H<h2 id="实现">实现</h2>; K7 b" X7 L3 v! u3 L
<p>为了保持简单,我们先定义以下两个类型:</p>
$ S/ I+ D7 M. Q! M6 ?+ C, |8 E<pre><code class="language-c#">// 定义新增Post的参数
. F4 o# n. ?# U' {. a, Zpublic record AddPostInput(string Title, string Author);
7 C/ r3 J/ ^" D/ {. l) |
5 j0 S; D4 s( u6 p// 定义新增Post的返回对象, ^ ^ s6 Q0 S$ d' ?2 t6 j1 x
public record AddPostPayload(Post Post);; _; a+ `, Y* U1 L
</code></pre> X! [# D% T' O
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
$ C# ]0 D! s* e( c: M<ul>& Y: ` u, u$ y- ^2 V
<li><code>Mutation.cs</code></li>
* b b! h; l& ^2 z% u, b+ N</ul>
+ _5 D2 A2 G9 F7 ]8 ?<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;) t/ t$ t- T+ Q- H
3 h3 E% T% n4 L! i! ~! |
public class Mutation
: U% y5 B: i8 y! J8 }* V4 z- {{7 @6 |4 s: _8 Y* p5 a" L+ q5 J; ]1 A* V
public async Task<AddPostPayload> AddPostAsync(AddPostInput input, [Service] IRepository<Post> repository)# |. [- @! ^1 ~
{
E! N/ B% u: I, l return new AddPostPayload(await repository.AddAsync(new Post& U5 T* Z8 B% I+ d2 H; g! E/ `
{9 k3 m4 o) e* \( z' x6 d
Title = input.Title,
/ O e$ c" O; N Author = input.Author' Y, H- R0 M8 g& X
}));
# z! G# r% y% ]# ]$ t9 F% S }
. |& a& o' e1 F6 l7 z6 ?}
/ `; d# C9 C! a. h* H3 J' F7 }$ e+ T+ r' V6 k9 w
</code></pre>
, P2 h$ J* Z1 r- D0 I! l8 H( c<p>最后在注入服务的地方进行配置:</p>
7 ^! s; Y9 F1 x% \! `0 O<ul>: s) g0 o* ~. M( s# p
<li><code>ProgramExtensions.cs</code></li>
7 f$ X `0 R5 Q& p, T/ J: D+ ^</ul>3 P2 C8 ~& u( }
<pre><code class="language-c#">builder.Services5 A$ H- C$ \5 b6 L* J
.AddGraphQLServer()7 z, z1 J( Z: T7 @
.SetPagingOptions(new PagingOptions6 ^0 q+ `$ C i2 H! P" f+ \/ E0 m
{
: ]% r2 ?/ }3 J8 ~# O MaxPageSize = 50,
; ^" w8 B8 s5 K: @# _ IncludeTotalCount = true' h/ a2 N0 e# X( W" Z/ g ~+ r% S
})
9 r, J, ^5 A5 g9 V/ r1 V6 y; F3 M: J7 d .AddFiltering()
1 h4 b% k- T) s. q% { .AddProjections(); _- o% g2 f% B4 S
.AddSorting()5 ]5 Y% \7 f8 X, {% h& T
.AddQueryType<Query>()) q% X- \+ s% b2 ?& G# ?
.AddMutationType<Mutation>()7 h! `& x9 `$ _- F0 q7 T* [" k. Y
.AddMutationConventions(new MutationConventionOptions
2 {$ W2 t$ v; a0 a/ ` {
( {, T$ P2 @ q3 P& T2 Z0 G: V ApplyToAllMutations = true,
; V. z Z9 u8 L* i* l5 ~ InputArgumentName = "input",% D: Q m! w+ u e5 S
InputTypeNamePattern = "{MutationName}Input",
6 U4 D$ `: [ i7 E9 \ PayloadTypeNamePattern = "{MutationName}Payload",
+ H8 |% h3 O/ Y. u, [! K PayloadErrorTypeNamePattern = "{MutationName}Error",$ ^/ k% A W: j9 y; Y% ^- r
PayloadErrorsFieldName = "errors"8 d) p$ W' N6 |. _. ~
})* i* F, h1 Z @
.AddType<PostType>();" r8 s! @" ]3 b- s. {
</code></pre>' I: c. m* V- Z' p
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
+ F0 b$ g8 M4 T. Y2 K2 q<h2 id="验证">验证</h2>! q7 W) G- }3 _. X
<p>启动<code>Api</code>项目,调用接口:</p>( V1 x7 v o* b; s/ ?' ^8 o
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>- g9 T7 s8 \, V/ J
<p>终端的日志输出如下:</p>
4 [$ a# ^7 {( I3 j1 O* j<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']4 P3 b- c3 K% D6 s8 a: D/ E
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
& C$ c, k6 r9 L; f6 q7 W, l" ]) `VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);* c9 K9 I3 z$ B6 Q9 R% }: t
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
# _6 U4 x5 I: U* }, [</code></pre>
+ S4 e$ E6 V$ Z: E) a6 q2 Q7 j2 j<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>! T) ]. L5 j- E" R1 c% Q& K
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p># T: X5 c8 `* z- v, Q
<h2 id="总结">总结</h2>" L8 W8 ^2 K! |, Q
<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>
% L0 S0 |. }3 |% d4 n! P<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
; u7 @) b) t* Q1 X, k( U" W, e. `5 G+ U- o/ H" Z' \' g
|
|