飞雪团队

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 12622|回复: 0

使用Hot Chocolate和.NET 6构建GraphQL应用(8) —— 实现Mutate添加数据 ...

[复制链接]

8019

主题

8107

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26387
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式

6 w7 t- Q$ P6 F<h2 id="系列导航">系列导航</h2>
% w9 n- Z: a8 Z; [; Z  U<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
# F" a8 }! \& `' s$ `<h2 id="需求">需求</h2>
: g8 A1 g6 h) U7 [' W$ T<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
: h5 Z5 }" |+ L  u( g0 D<h2 id="思路">思路</h2>  E1 O. b# p: A- N6 ]* _0 V
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>" d/ t- P+ c9 J+ L# `
<h2 id="实现">实现</h2>
$ L5 U* r- O( {. E<p>为了保持简单,我们先定义以下两个类型:</p>
; r6 O0 R; k4 D% F<pre><code class="language-c#">// 定义新增Post的参数
9 X& a3 D% C8 o5 ^, \/ ipublic record AddPostInput(string Title, string Author);
( z; X/ R; n4 `7 T2 G& P9 _! W" Q) K5 L- g3 \# q- r
// 定义新增Post的返回对象
; T9 T/ v' Y; N- }. p1 l; W1 _public record AddPostPayload(Post Post);
! A# b! Q' f5 s9 a/ G! r</code></pre>: v9 f, s7 T6 O. m0 m- j
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
0 m, l4 h* w% d6 q% u8 z1 ^<ul>3 h8 a. b8 b0 {( y# I' U3 p/ n
<li><code>Mutation.cs</code></li>
  A; u8 z4 @0 J# Y# y" C</ul>/ n1 i3 e' j5 U3 s  F" B
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;; L) v5 X. ]2 [2 K, O+ s
) u' @, n; P" w1 N0 |' a+ g+ y
public class Mutation; q' g, {1 V( u- d4 ^
{+ b4 k! q; c$ T3 X$ j3 E
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)( V! W- K$ w- v" k2 [
    {& ]! P; @( }- C2 r2 q6 _2 Z
        return new AddPostPayload(await repository.AddAsync(new Post$ n( P; H, y! @/ o  [7 a
        {
; S: ]: N% z9 i* x7 _) V            Title = input.Title,0 I' T* O. V4 g( s9 A# j  p
            Author = input.Author
& F, g8 Y* r% }! x  ^  F        }));
" g( M7 G7 q2 I0 ?' f    }. P3 {4 O1 b" M, N. ~
}
7 i! t) ]& [- P. M& ^
8 G: \: l, V& ^6 @6 j: A0 W</code></pre>
$ e2 X% v+ \  G<p>最后在注入服务的地方进行配置:</p>, g* e0 K: q! E8 C
<ul>- f9 B7 ^# J$ @& D/ C& v
<li><code>ProgramExtensions.cs</code></li>
) g0 l# s7 n& _% S% t</ul>
  k  T1 `2 Y( R% J  }. r" i; J! X8 X<pre><code class="language-c#">builder.Services
" ]- x( N3 H: _7 n. g    .AddGraphQLServer()( t6 g$ m" f* t
    .SetPagingOptions(new PagingOptions! `, d5 k1 q: ~6 i
    {5 f5 d8 _9 ]4 A
        MaxPageSize = 50,
, J9 y$ ?+ W+ ~$ \8 K        IncludeTotalCount = true7 }3 W7 S2 r  b5 f0 F: a
    })7 b0 H8 J* g8 L. I! F8 S
    .AddFiltering()
# ^2 A  ]# ?8 J% S2 y    .AddProjections()5 t' \9 {) H7 {  t
    .AddSorting()9 b8 c2 m4 f2 t9 O& s- O7 y3 W
    .AddQueryType&lt;Query&gt;()
- V+ U& D! v% C    .AddMutationType&lt;Mutation&gt;(), r2 C, D7 b3 {4 D/ f5 q9 a
    .AddMutationConventions(new MutationConventionOptions7 ]! ?& y4 m9 M+ i2 M
    {6 n+ V8 C6 q) J% x( ]' m
        ApplyToAllMutations = true,$ D) E; R+ H/ m* d4 _5 F$ G
        InputArgumentName = "input",, _0 `' c/ }/ S7 H
        InputTypeNamePattern = "{MutationName}Input",9 N8 x" h& i! L3 W: j7 [
        PayloadTypeNamePattern = "{MutationName}Payload",
+ ]% q( q/ I4 E9 I4 z* k8 U        PayloadErrorTypeNamePattern = "{MutationName}Error",
3 P8 L5 _- {% q0 h6 `9 r( `, D        PayloadErrorsFieldName = "errors"1 B, M3 S4 b! W. `  ^: m2 K0 w2 L
    })' O2 x, ^# y6 C& e# P4 W
    .AddType&lt;PostType&gt;();- U1 X2 B0 ]+ W- L- u
</code></pre>
/ m; c/ B9 A8 Z( J: ^: L" X" W<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
8 w3 S% |3 k0 s. K<h2 id="验证">验证</h2>% G' L/ l: m5 ~+ ~- B, {
<p>启动<code>Api</code>项目,调用接口:</p>
9 x  Z( D* V9 h! G. Z: e- C8 m9 l<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
0 Q. y* w' T) t, C<p>终端的日志输出如下:</p>0 Y- {- M, A  P9 h# l; X7 }
<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']
: _" a: z5 G4 b8 q- YINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")5 G+ p/ ]1 z; v
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);9 r. w9 r2 x& Z4 ^5 W. k0 a: k
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'+ O, ^; R# e4 ]
</code></pre>
# x2 y# V, Z" s" J5 M, o/ N<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
& Z4 \/ Z1 j& K) O5 S) u" e<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
+ Y9 N$ N& I9 i1 y<h2 id="总结">总结</h2>% T1 O/ I* W: l9 c* e# U; ]
<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>6 a7 ?$ m! j3 O& L1 h0 J
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>, m2 F$ f9 p! \( K
6 e( M; x: e8 o
回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-1 22:15 , Processed in 0.064494 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表