飞雪团队

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

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

[复制链接]

8119

主题

8207

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26687
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
- c: p8 X. S3 t1 R
<h2 id="系列导航">系列导航</h2>
. g: E5 A# {! B/ P' N# ^<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>" [6 ?" u( T4 l* I, v3 t  f
<h2 id="需求">需求</h2>/ ~) P: z6 h9 Z+ y
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
- r2 a7 Y2 F& Y6 B; A! @6 U<h2 id="思路">思路</h2>* H  u7 w' M! ]) x4 h; P% m
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
) R- v8 q+ f* N8 E  }<h2 id="实现">实现</h2>+ A5 m6 y1 @8 a4 P
<p>为了保持简单,我们先定义以下两个类型:</p>
/ \/ a  d5 T/ K, h" x<pre><code class="language-c#">// 定义新增Post的参数
+ P+ d5 u$ G$ T  C9 [public record AddPostInput(string Title, string Author);$ J& U7 n; A: K3 d& t) C
! b* J2 i1 x! S
// 定义新增Post的返回对象  i8 I* d$ a7 j$ c. p/ ~6 R) C
public record AddPostPayload(Post Post);
8 u2 e1 W! {" Q9 l) W) X</code></pre>2 t/ K& f8 H  m) P! ^: b  K& K- N
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>4 C( y( ~: x( I1 H. h) K9 D
<ul>
7 j2 }$ J& V% \+ Y0 o; l1 E<li><code>Mutation.cs</code></li>7 R1 |: t6 n$ J+ }5 E/ p
</ul>
: }& ]- f, H& A<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
/ y5 ~9 Z0 P! B, Q. I( s( z) u; V' H& W7 K
public class Mutation- I1 V% ^, c) E2 n  ?
{
2 x/ R  U: P% [" u    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
% D9 f4 ~0 Z  _: A) Q3 _, m, [# |    {
4 [: n5 `4 ^. M7 `6 M- h0 L7 X        return new AddPostPayload(await repository.AddAsync(new Post* }: A2 G0 _! \' e+ s4 O5 D& O6 `6 ]
        {! x! C# M& }5 P2 N# q
            Title = input.Title,. H' n% |  c3 ]; O( g; t
            Author = input.Author
- }. m7 f) p9 C" q" L/ E        }));$ @5 e% G5 ?6 I; U! d' L
    }
3 r2 Z; [" A9 k: _& V$ \% m* E}% h' P1 x, a: I& N2 L8 p+ B" I' Z% I( _
( X3 _& t6 z  ~' Y( |$ E. K6 Y# y
</code></pre>
8 u$ f/ p7 p- M<p>最后在注入服务的地方进行配置:</p>
* F4 ~, p' N8 T<ul>( p( p5 G2 I" X" ?$ _
<li><code>ProgramExtensions.cs</code></li>) M8 o: q0 \( P$ X; A% E
</ul>. }; |3 N  ~5 y( A$ X/ I
<pre><code class="language-c#">builder.Services* D+ M  C0 ]2 p: P
    .AddGraphQLServer()9 H/ u+ o" k: b$ m
    .SetPagingOptions(new PagingOptions
- C7 W" _& U2 p/ s: C- {    {
! D" x1 N  Q& B& a* u- X3 }        MaxPageSize = 50,/ O; y! M9 m. I6 \# A
        IncludeTotalCount = true' {1 e0 K# [4 `; [1 P% Y1 t4 j  d
    })
" F5 g2 g: q0 j4 j    .AddFiltering(), x' w9 A- P7 c1 E+ X
    .AddProjections()+ a& b6 L0 j& T  T; y
    .AddSorting(): w4 z+ o( c* @/ y0 _/ p) Z
    .AddQueryType&lt;Query&gt;()
% ]8 A1 X, g' Y& D8 t5 K    .AddMutationType&lt;Mutation&gt;()- l' d2 {* d7 J/ I
    .AddMutationConventions(new MutationConventionOptions
) X" @& G( @% _5 B    {- _5 M# ?: j: m
        ApplyToAllMutations = true,
2 n; X! @& f9 D1 X        InputArgumentName = "input",! ~/ F: o! d6 Q# Y+ n
        InputTypeNamePattern = "{MutationName}Input",
% n( R2 y2 Z+ N% t, y        PayloadTypeNamePattern = "{MutationName}Payload",
" A; x3 N# D. v5 Y- A        PayloadErrorTypeNamePattern = "{MutationName}Error",
* t# y( M1 k: [+ E0 X' b        PayloadErrorsFieldName = "errors"
: U+ l3 C8 K1 {. [    })+ L+ c& [2 c; B9 e3 h2 P0 [8 }- v
    .AddType&lt;PostType&gt;();
  n- ^' }" W5 _, ^& H9 i, @, {</code></pre>" I% \- s. d0 J' R
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>0 D1 ?* |9 {4 G* r' h
<h2 id="验证">验证</h2>
% S0 ~$ u4 C8 U" v6 f! Q<p>启动<code>Api</code>项目,调用接口:</p>2 N: h% u6 x: @( m7 ]  n
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
' D+ ^& z% L0 a. R1 e* L<p>终端的日志输出如下:</p>
( j. d+ Q  N0 ^9 C( S<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']! _4 s/ ?5 l2 F7 s' z1 m
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
/ y! ]/ X& y3 W% [' OVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);2 L6 B. |# s  o$ r9 D
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
$ |. S9 N  T% m# }: O* R</code></pre>
2 U- T! f* V4 @1 p& @0 \" _<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>) {# ]% K1 B8 h4 Z  r8 I
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>8 [: T7 `- ], y- {9 t6 ~1 E
<h2 id="总结">总结</h2>3 M8 A6 R; Z. J3 E9 a5 m
<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>
5 C" t7 g) p/ I- C<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
( ~0 [, Y" S: V# D: k0 f- q' N; D5 S% J7 w/ m8 M* a, ~
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-23 15:05 , Processed in 0.065766 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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