|
|
; P0 ^" Z' q8 i! H4 j- R/ K
<h2 id="系列导航">系列导航</h2>
+ z) c f4 y% m9 ~1 Y<p><a href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>. l2 d5 h# \, M' |* V. B
<h2 id="需求">需求</h2>
5 U2 o; d1 M0 N1 E, k' h1 v<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
2 p2 X( ^' S- r: j<h2 id="思路">思路</h2>
, M) i$ [9 X6 K<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
5 }8 ~) R, g& Y4 P6 r0 Z<h2 id="实现">实现</h2>* e0 L. o. `9 `
<p>为了保持简单,我们先定义以下两个类型:</p>3 Z) g k2 Q: ~0 {3 q
<pre><code class="language-c#">// 定义新增Post的参数
. N |& d+ I; r3 i$ J, rpublic record AddPostInput(string Title, string Author);
+ G) g% {) O) b6 r
6 p, `6 { ]6 N \, t: v% {// 定义新增Post的返回对象6 J5 E* m. c7 K
public record AddPostPayload(Post Post);
, M5 J/ |- W, y</code></pre>
8 H, m: D5 [+ I$ f7 D<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>4 i8 w0 Q5 D, Q$ B; j! Y# ~" K" j
<ul>
# B& V S5 X* R% y1 j<li><code>Mutation.cs</code></li>$ t$ Q5 }( E3 W8 d, S1 o* m/ a
</ul>8 @; l* z- T5 {. h5 o, _, {
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
@6 H7 b- \8 b8 X* z+ k, E; |" [1 V+ [6 p: t
public class Mutation
6 Q, N) d/ t( L1 e/ D{6 w* J! ~2 `; I6 u5 l9 S# B
public async Task<AddPostPayload> AddPostAsync(AddPostInput input, [Service] IRepository<Post> repository)1 n3 [+ u( |/ d( C
{3 d9 x1 o+ U4 }* f- w
return new AddPostPayload(await repository.AddAsync(new Post) G# u- w+ U, M9 j
{ p( P- S! G0 r2 e
Title = input.Title,$ p' u% S% J- |+ w/ \. j+ o
Author = input.Author- X; K( o) O8 z
}));' ?1 N# P8 `: }; T- G4 c
}
0 E; D3 R8 V1 c5 c( h5 o& c& b' u}
) K+ N6 p' K1 u8 d3 J7 R# ]2 k& W* V" s) |5 W3 }9 G
</code></pre>% C2 k8 Y, E7 t8 [- E$ e
<p>最后在注入服务的地方进行配置:</p>
! }1 s" G5 a1 Q' ~ d<ul>
: ], U' D; G" M<li><code>ProgramExtensions.cs</code></li> B3 d* D5 m5 M* F, P* l
</ul>
" s/ d! G3 e% q1 Z+ q<pre><code class="language-c#">builder.Services
8 v0 C- h- e4 e .AddGraphQLServer()1 I v/ I! K2 s) }0 g# `6 [
.SetPagingOptions(new PagingOptions
7 q; {+ ~2 t) m. f X" I# o# B {3 P( Y! H& G3 H- u1 V# i$ J
MaxPageSize = 50,
( W {8 y$ ^; g9 \ IncludeTotalCount = true
$ F8 ^0 J+ |6 K* X! r9 H })4 `% }. L* U# e$ j. ^
.AddFiltering()2 T1 W& [) @0 g# B5 u$ J h
.AddProjections()
& j, b! s3 |& s& n" z .AddSorting()
9 f: u7 Y% r ~- G/ \ .AddQueryType<Query>(): v8 ^; w( s* C- y* |' u4 F
.AddMutationType<Mutation>(). r0 c: P) Y, M
.AddMutationConventions(new MutationConventionOptions
( A* b$ f) S( u8 s- h/ s2 N! A {2 I. h3 v+ O" }3 n* M
ApplyToAllMutations = true,8 J- M" f) t4 l7 `* S/ A* T
InputArgumentName = "input",
V% E2 c' |1 k" I InputTypeNamePattern = "{MutationName}Input",$ w {- i% X" E. p& Q2 v7 W2 [
PayloadTypeNamePattern = "{MutationName}Payload",
# u) S: t2 Q) C7 u( h2 ^7 h. O( d PayloadErrorTypeNamePattern = "{MutationName}Error",
1 j- G, o- n4 }* o, f4 ~ PayloadErrorsFieldName = "errors"6 w8 N: a+ v9 N$ ?9 U- o
})+ I3 f7 z/ Z: @$ i& c
.AddType<PostType>();
6 p3 L' Z! f# s0 g</code></pre>
4 L( L, l& O" I( ?, U/ K. b; Q<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
- Z, j) p3 E0 G. E<h2 id="验证">验证</h2>: q7 B% w5 \6 }
<p>启动<code>Api</code>项目,调用接口:</p>& s8 _* D$ y' @% h6 E
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
T! R% _" {# c. f! t3 M<p>终端的日志输出如下:</p>
- d7 f/ y3 \6 v3 [) a5 Q<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']
" Z5 H9 ~+ d( p% HINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
! p9 S u) @5 c% }& s# |VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);$ B+ K x4 V% _9 L9 A
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline') L# m3 [' X( s6 A' l! q: g& U7 T e
</code></pre># Y: ~& Z, B' g q% H, e7 d
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>6 Z0 d* t3 q( o3 z R
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>! Z$ h# e$ E9 t# c/ K' x
<h2 id="总结">总结</h2>! w) k' V- U, {% Y3 R7 D9 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>9 o4 R1 c- F! v) t) d) I! D: I
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p># j8 h2 v& `% D" J/ f+ r
6 \) D4 B( U) A$ j. z
|
|