飞雪团队

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

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

[复制链接]

8834

主题

8922

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

1 A% o4 S  M7 E<h2 id="系列导航">系列导航</h2>1 t- l0 K4 O( w( A+ C" v
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
! T* q, L% o8 w0 Q- U) x& W7 z5 Z<h2 id="需求">需求</h2>
9 w& q/ j  [9 q  w* u<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>1 d  W( M5 q$ Z" F9 C
<h2 id="思路">思路</h2>
# x) P; E' F/ z<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
/ Y7 @4 D3 D# X$ d& O9 K<h2 id="实现">实现</h2>7 i9 @/ H$ F8 Y8 L6 V- D
<p>为了保持简单,我们先定义以下两个类型:</p>
; X. X, Q& C3 [% O; ?. U; M4 _<pre><code class="language-c#">// 定义新增Post的参数; I6 M2 o" k7 S: u
public record AddPostInput(string Title, string Author);- f- t% }* ?7 ]9 O* k, ]

( C# ?/ L9 K7 A; v( H/ ]// 定义新增Post的返回对象
' g$ E2 e2 H$ V& Ipublic record AddPostPayload(Post Post);
' [9 y) P: V- a& S2 u</code></pre>
& M6 M( b% N; S<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>0 K0 f9 E* r: C1 Z% f4 S) X
<ul>: t- k3 p' ^# U5 w
<li><code>Mutation.cs</code></li>
, ^; e  O2 c) e: }& }( m</ul>6 v/ f% y7 `0 q" }
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
+ X" R& V) n/ x7 @/ \% L6 g
7 t; Q# I/ j2 U) V3 i! s# q  ~% k! _" upublic class Mutation1 j% e- d1 V; {
{) X( T5 E$ ]" l$ y
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)4 w" d2 {& ~! B3 b
    {$ D0 n, D- J; a  F+ R* c6 \
        return new AddPostPayload(await repository.AddAsync(new Post
5 a1 ~" r. O! A& y% |" a; ]        {( `/ r" M8 e2 ?& ?9 e
            Title = input.Title,
& u8 g1 L2 R9 r% L+ P            Author = input.Author
3 d+ a% C: B* _5 h5 }        }));
; p9 K3 e5 b$ N* L. `, Q4 B    }
5 V: [; i' q+ p4 f}
& C6 B$ N# V  g& [
7 t' F' `) S5 z7 B$ V</code></pre>! J" C( Z$ V5 z6 s' c0 A
<p>最后在注入服务的地方进行配置:</p>
+ _% q* f/ ]& K5 U! `( c- U<ul>& P" Q" w0 I2 N2 f  V
<li><code>ProgramExtensions.cs</code></li>
/ M, K* `) M5 R6 y# W</ul>( q" u8 B: z4 L0 X2 @
<pre><code class="language-c#">builder.Services  N, A9 |0 t: K0 }* v  B3 |& t
    .AddGraphQLServer()
4 b7 ]% q# Q" {9 R7 _    .SetPagingOptions(new PagingOptions. W/ r5 Q, r$ a( e& _
    {$ @1 \+ \7 D" x  c
        MaxPageSize = 50,$ W% `# U" W4 |( c. O
        IncludeTotalCount = true4 G9 w9 o5 t* F" G+ L: \3 }
    }): ?, ~. b/ ?) m& c8 }( W; _
    .AddFiltering()
. G: q* U3 T6 ]" I- M0 ~" U    .AddProjections()- i- c* N; x, h; r
    .AddSorting()% A- H/ M( g2 b8 |1 S4 v
    .AddQueryType&lt;Query&gt;()
9 f+ A6 ~1 p; X+ [4 Q    .AddMutationType&lt;Mutation&gt;()/ H* i6 z! [6 o* @
    .AddMutationConventions(new MutationConventionOptions
! U: V" B8 l; v8 l& @  X# a    {
4 b# B$ _9 v. r5 c7 u! O9 n! v$ G- a        ApplyToAllMutations = true,
: C5 {$ |! W" `4 B; Y        InputArgumentName = "input",7 |- m$ C1 B, W. G
        InputTypeNamePattern = "{MutationName}Input",
+ ~, {& _& n5 U! x, Z8 ]8 y        PayloadTypeNamePattern = "{MutationName}Payload",
  u% n; t+ Y0 I% ~) M6 S        PayloadErrorTypeNamePattern = "{MutationName}Error",
: l6 O, w6 Z2 t4 |        PayloadErrorsFieldName = "errors"
1 O) |0 S1 ^+ u) I0 g: _" v8 }    })/ i6 O7 c; q" v1 W9 n
    .AddType&lt;PostType&gt;();5 l; |3 A+ M% ^+ ?) {3 \& z
</code></pre>
# D3 Q! }1 k( ?% t" {8 Z9 A) G<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
' E- ~* I# R6 `4 A# Q<h2 id="验证">验证</h2>
( ?' \$ }1 T% Q' a% g<p>启动<code>Api</code>项目,调用接口:</p>
5 G& u, A& l* Y! ]$ u' V; o<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>  o( {* K7 n% o2 \9 p, @' y
<p>终端的日志输出如下:</p>- e( c$ @9 I/ Y3 I
<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']
/ i6 D3 m3 z, m! W  jINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
7 U# [# P$ F% d7 X  ~+ BVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);8 T' I3 c) w* \% T" z1 @3 s
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'& j" `& N' c+ o
</code></pre>, ?2 t0 Q9 K) R  e
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
" w% ?: Y" F+ j: M: |4 M5 U4 t8 v<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>7 Y) y. E! `# M3 }4 i
<h2 id="总结">总结</h2>
0 f* n1 t3 R( J6 T3 z" M" L0 S3 J4 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>
: a' f6 b/ @1 R, H; L. U5 C<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>! f  U4 ?, ^! M
0 Y$ i! S" h+ q! p4 e
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2026-6-3 08:51 , Processed in 0.065877 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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