|
|
- f+ L# d# I$ I/ N5 @
<h2 id="系列导航">系列导航</h2>
* `* E7 H( F+ H9 _2 }) P8 x5 o<p><a href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
' k, Z6 _6 Y% x: N<h2 id="需求">需求</h2>
: P Q k3 \& ~' `' P, x<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>0 O* T8 S" W% c2 Q4 ~6 a
<h2 id="思路">思路</h2>! u( a+ [4 i# z' J
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
/ M5 H% O& G( l' D& B8 ?<h2 id="实现">实现</h2>
9 v# G% ~% S2 `7 V0 L3 z+ I<p>为了保持简单,我们先定义以下两个类型:</p>
5 P) ?' N- m" Z* k9 o& B<pre><code class="language-c#">// 定义新增Post的参数6 |+ ~9 f( u0 c7 j! g; ?
public record AddPostInput(string Title, string Author);7 ]: @8 t& A# U4 e$ \4 T
! n) K& }, v1 ]// 定义新增Post的返回对象4 B+ b$ d7 j8 `* T$ I7 r
public record AddPostPayload(Post Post);
4 M% l6 n# A" ^! ]: n</code></pre>- m8 O) f/ j! @" r, K/ j
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
& c1 ~" @$ x: D2 T2 X<ul>" S8 e- N6 z! l% T) G j2 _
<li><code>Mutation.cs</code></li>+ L. s; T% B8 R1 i( S: s! z, ^
</ul>/ C! m# I! y( F. H% d
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;( @1 W( g8 Z" d6 |4 ^5 J9 u
8 G& C1 s* S" r3 S: B$ H) J2 s
public class Mutation! U9 p9 E2 y7 M! u
{
! q! ] x0 X7 X U7 z0 E9 D public async Task<AddPostPayload> AddPostAsync(AddPostInput input, [Service] IRepository<Post> repository)' P9 t7 \3 R8 Y
{
! a5 Y- @) G" K) H, K return new AddPostPayload(await repository.AddAsync(new Post; t$ H2 q0 N9 [" p- T& t
{$ x+ ~5 V0 s% n6 W( M, E( w
Title = input.Title,5 }# Y/ I+ h" }# } x
Author = input.Author
. v/ W; k$ l9 r/ O$ S; ~/ a4 W' Y. C }));9 Z ]' u, M- {
}' q/ I$ Q8 A" z
}+ |, g( [( W' w7 B8 Q, E
4 Z# c! s, T ?8 R% _
</code></pre>1 L3 B9 q' {( @% T* C
<p>最后在注入服务的地方进行配置:</p>% i1 I' ]& b+ t& q1 t: r$ I% a
<ul>3 `9 O! @6 b1 g Z d8 m' H
<li><code>ProgramExtensions.cs</code></li>. P' R U! G! U# r
</ul>" T( |$ k9 V1 a" f# H3 c/ ?; C
<pre><code class="language-c#">builder.Services
: W' r& s% D6 b .AddGraphQLServer(); {0 e) |: D2 c6 u9 Q" ]
.SetPagingOptions(new PagingOptions: c8 o9 H. V9 C- O
{( R1 o! u0 q6 J, \4 y- U1 _
MaxPageSize = 50,- a" B9 h; ~ [1 Y9 j
IncludeTotalCount = true
! b( a+ S5 n' i5 C })* Y$ B) w. O; c' V, l( a
.AddFiltering(): T p+ K: Q4 C6 [, O4 l
.AddProjections()
`. w* y0 U- M, _& E .AddSorting()
/ y! V4 p$ l3 Y6 R# S .AddQueryType<Query>()
- a0 w% V& w/ ]9 [ .AddMutationType<Mutation>()" ~1 n% ~2 H- @' T6 Z' E
.AddMutationConventions(new MutationConventionOptions
3 s1 h8 {) v: }, f: Q- S {8 \$ ^ o: _6 b# t6 E7 n. t, B/ ^% {- b
ApplyToAllMutations = true,
* Y' e( z0 i; x2 t" W. E InputArgumentName = "input",
8 V" f* {2 E" q: X9 i InputTypeNamePattern = "{MutationName}Input",* b* p- R( \9 G$ l$ P- V; D& x+ j
PayloadTypeNamePattern = "{MutationName}Payload",
) v! Y$ P. h3 O8 O9 h( A" ] PayloadErrorTypeNamePattern = "{MutationName}Error",
# |0 P- r- L# A" ?5 @4 P# n5 \ PayloadErrorsFieldName = "errors"
6 A J- j/ b; v" N4 ]: T })2 b3 Y) r9 N! c1 i
.AddType<PostType>();
; @( n& Y" K4 I: m% c6 Q6 l</code></pre>
% A3 K$ P& }& Y; ?* X) Q% _<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>! w% ~" O& i" S* `; h$ i
<h2 id="验证">验证</h2>$ B3 V# M* P$ Z, b3 g; A+ L
<p>启动<code>Api</code>项目,调用接口:</p>
( G$ i6 z% j0 Z) }! g<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
# D5 Q' a; o1 Z" b! I<p>终端的日志输出如下:</p>8 @6 [. L( F C+ F( l
<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']
, K8 q: Z; D1 w6 `INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
2 D+ a! T. q; g' a5 m& b9 KVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);, N, S5 |( z, T7 N; J( |
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
9 s; ]# j: [2 n" n</code></pre>- {) r1 k, o6 V4 H5 Y
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>1 {5 w" \) ]1 ?/ N" S! t: p! @
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
% |& S a8 c: t3 ?; \<h2 id="总结">总结</h2>
! Q+ {4 \& k5 Q* n+ _<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># @! }: A4 c# l
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
3 S& N' ? O7 l) v6 T8 G( J9 ]; G& a# b+ ~7 Y! G1 E
|
|