飞雪团队

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

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

[复制链接]

8038

主题

8126

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26444
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
2 U: m' y, t. ?4 z$ b
<h2 id="系列导航">系列导航</h2>
8 S/ L7 n2 F' ~4 [<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>: A6 v2 @+ L5 B& K  L- G
<h2 id="需求">需求</h2>  P( o1 a, r9 i, `
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
  \6 w/ h9 I7 ^; W9 }+ \8 C<h2 id="思路">思路</h2>
) `5 I6 M$ Z! M<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
/ p* P6 _3 o1 G<h2 id="实现">实现</h2>
1 _6 f' O( R9 y: s$ }5 i+ j<p>为了保持简单,我们先定义以下两个类型:</p>
! b5 q# n1 `. u; Z# x7 ]* `" Q<pre><code class="language-c#">// 定义新增Post的参数6 z6 C/ Z+ m( |- u. E" g. N5 H* @
public record AddPostInput(string Title, string Author);
$ ~+ P8 h- `9 {8 `: n
7 C) L- x5 v1 |7 _% i  A// 定义新增Post的返回对象
" O) u& R% J+ Y9 h2 dpublic record AddPostPayload(Post Post);/ }5 G+ C& ~8 z7 f6 o/ I2 f* ]2 o
</code></pre>
5 V+ R8 u( {8 [8 h7 e& q<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>0 d$ J: V: U: S9 n& X  s( U
<ul>
6 S0 M( T7 {: q" e; Q9 {<li><code>Mutation.cs</code></li>+ Q( p. O$ Z. h; A# V
</ul>
! w: Z7 N$ h6 d9 I, f- m<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
' I. L: D. }0 h* G# d3 A! m0 l4 \1 ^+ _, t/ M' m, z. s
public class Mutation
& ]3 J, @0 w; ?4 t{
( l: L! x' |( I* j8 a$ y+ x    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
. l5 y1 d, c2 i, j4 }! @    {' F' m4 t* O4 _, R
        return new AddPostPayload(await repository.AddAsync(new Post
9 H, `& U- `$ s: d: l        {) N: E( y& \8 M" b
            Title = input.Title,7 W8 Q1 b# v, R9 `' W0 Q/ `: M
            Author = input.Author
7 [: V) N0 @4 u6 y: y. I. c        }));
- ?; D$ P1 u# e+ K% b9 n( |# P    }" \! v* z5 D1 H
}
5 n" [  Q) j! b0 F( U5 N0 a& z
$ o! b- x2 O5 c8 }2 Z8 T</code></pre>. P9 s9 P9 ?3 |
<p>最后在注入服务的地方进行配置:</p>, v% ]3 T. g5 N
<ul>( s5 z% p' J, \5 }2 f( d
<li><code>ProgramExtensions.cs</code></li>
, U8 h: m: N( j</ul>
" K8 b6 E6 V' |8 f8 z7 ~8 @<pre><code class="language-c#">builder.Services
0 ]9 F) H% w& B' C    .AddGraphQLServer()
3 M$ t9 M- A3 B$ @- b2 y( z    .SetPagingOptions(new PagingOptions$ I8 D8 _; n2 ~% x* G, S  S+ Y
    {
) `& R% E) c; S- t1 a0 [        MaxPageSize = 50,
6 Y' @) A0 A6 J. r3 v* t        IncludeTotalCount = true
+ x1 I. g0 I- E0 |) W% U    })$ s9 M  E' q+ J& C8 Y7 @% ], }4 Y
    .AddFiltering()
( Z2 h2 @% w3 ^% U: {" C2 l    .AddProjections()
: o- H% H! C' f9 v2 I, C7 k    .AddSorting()
( x0 \9 F# E7 Q: C4 Q    .AddQueryType&lt;Query&gt;()
8 }; {. n- N( ~- a& e5 N5 M! w: j    .AddMutationType&lt;Mutation&gt;()
0 A9 {5 t8 Z5 t8 M) d5 x1 a- A    .AddMutationConventions(new MutationConventionOptions
" T" x6 V$ m* t/ Z    {, @1 h) h$ G. R! Q: N
        ApplyToAllMutations = true,; q9 U/ m8 B$ [2 a' B! p
        InputArgumentName = "input",4 [" A* t% C, z5 S5 y
        InputTypeNamePattern = "{MutationName}Input",
! p" \& I' ]. W* P        PayloadTypeNamePattern = "{MutationName}Payload",+ O! F) j: ^" e$ Z- m* ~$ `3 N
        PayloadErrorTypeNamePattern = "{MutationName}Error",
: R5 m! ]. G& I        PayloadErrorsFieldName = "errors"
6 F3 @1 Y8 ?  Y0 h! s% v; m    }), L, }, b- U7 o3 ~
    .AddType&lt;PostType&gt;();
3 }, X) O& R/ b( q8 W, r( P/ A$ k- E</code></pre>) Z/ ^6 K9 D+ V+ b9 G: Q! O7 R3 \  ?
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
) i. P9 h- O3 y. L2 ^9 I<h2 id="验证">验证</h2>; s: n0 P! y5 h; u
<p>启动<code>Api</code>项目,调用接口:</p>
2 e3 Z8 S, D- C9 D<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>- `) Z7 i' N* @0 A  k7 z, g0 D( F
<p>终端的日志输出如下:</p>
& c% o: k3 q& v" X! G4 K<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']( C. V7 x* \# h  V2 Z
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
6 R% J! M* h. g4 \3 @; ]  }VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);: N, h, ]: Q6 z, M
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'4 C4 v5 S2 d( X, s
</code></pre>5 q5 Q; D1 f4 u% y
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
/ e) h" B3 P' N$ n<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
( Z1 Y0 K% K8 }7 X3 J" I+ X* q<h2 id="总结">总结</h2>' Y8 t8 F5 j3 u0 ~
<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 \$ y! w+ Q2 d( B# ]/ V$ F) S
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
$ J( n+ ~# A3 _3 o  n- C
: |) w2 [$ n& t5 @% \" o3 U, Q
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-5 14:49 , Processed in 0.067676 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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