飞雪团队

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

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

[复制链接]

7903

主题

7991

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26039
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
- t( S' e" U$ M6 h- o5 `9 G! o/ P8 S- r
<h2 id="系列导航">系列导航</h2>
4 W5 J) C7 A* s/ a<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
4 J1 F6 @: q, X' e<h2 id="需求">需求</h2>" a/ i$ k: D) H
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>1 \0 S/ H% u! n1 E$ J
<h2 id="思路">思路</h2>) i& _2 Z6 m) a5 o1 k
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
- D# c4 C" m! Q& V( L- w+ `<h2 id="实现">实现</h2>
& ~( A8 g0 Q( V1 |) P<p>为了保持简单,我们先定义以下两个类型:</p>
! \# [" @7 r3 T<pre><code class="language-c#">// 定义新增Post的参数3 W5 L) b( |* n" r! e/ J
public record AddPostInput(string Title, string Author);
2 g7 _- Q2 K1 x6 Q4 d% S
6 h% P* E$ t5 M2 o! ]. n// 定义新增Post的返回对象
) T+ R8 L) u9 F: `0 H$ m  A: @8 apublic record AddPostPayload(Post Post);' ?$ P6 B/ ^( Q4 J0 s/ B9 ~2 ~2 y0 Q
</code></pre>
( U  d3 p# U4 W3 t3 O% `6 T6 S) {<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
/ Z0 f9 y+ R' [2 `8 n. e+ j* I3 |<ul>' U" M; u5 z9 ~3 E6 V, a# e
<li><code>Mutation.cs</code></li>
3 }2 I( ]: `& x/ v) V: o</ul>
( Q/ ?. {  e# _+ x<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
% B! K+ f: f2 ~7 X6 c, l" w# h  J! _8 u- e/ b0 C
public class Mutation: v  A+ F8 Z  ^2 _2 |, K% H
{
  O/ S# Q* A* P9 ?$ k! V    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)* C* `$ b- s: I; P5 z, ^
    {
$ e/ l& P- F6 U# E. N5 M        return new AddPostPayload(await repository.AddAsync(new Post+ l) ?! y& J$ N
        {
" v5 `/ K/ a+ P  H5 Q            Title = input.Title,1 ^0 X9 E; h3 I# y  }! i
            Author = input.Author& P) y2 l1 |  v2 a
        }));9 w4 K5 l( F) W
    }$ _7 g- u$ U/ U2 U
}
9 l, d2 K  ]/ h8 ^0 e2 f$ v) s4 S3 U( {- M& q
</code></pre>
  n: M6 }$ t& W) n0 J! r6 c% k<p>最后在注入服务的地方进行配置:</p>' m; I) o! K- v# z
<ul>5 ]. X: \6 e+ @0 w  \; J
<li><code>ProgramExtensions.cs</code></li>
: R. r+ x  m; l</ul>
& C! l7 K  a4 H# Z" v<pre><code class="language-c#">builder.Services6 |3 u, C+ W- [$ T( K
    .AddGraphQLServer()
( v, {: L( |1 |8 F# g    .SetPagingOptions(new PagingOptions4 u" G7 Z2 V( d0 j; W/ C
    {- W) Q, T) c) a$ R5 D( j
        MaxPageSize = 50,: K: M7 d% E) @8 g
        IncludeTotalCount = true& d2 U  e7 \& m  i/ w2 T
    })* A* a- |! E6 v* p( b. l9 ?
    .AddFiltering()
! t4 H4 e# a3 W9 x9 _2 f2 v    .AddProjections()0 G3 E) I; t  C, X
    .AddSorting()
( A2 l7 R! ~6 R. M. W$ Z    .AddQueryType&lt;Query&gt;()" y5 J+ e1 L5 e8 d' I
    .AddMutationType&lt;Mutation&gt;()
  k# j3 I) @: b8 Y  K    .AddMutationConventions(new MutationConventionOptions* K. \- G) q+ Z6 c3 F/ r* u. T
    {% N: `( G. J  K! E: g0 J
        ApplyToAllMutations = true,
' |8 h, E1 R2 G        InputArgumentName = "input",. b" C3 L0 O: u3 \/ ~0 S) c
        InputTypeNamePattern = "{MutationName}Input",& w5 ^! H: C/ b9 u
        PayloadTypeNamePattern = "{MutationName}Payload",9 M! l. W" Y  D6 K
        PayloadErrorTypeNamePattern = "{MutationName}Error",8 s- v) _. m7 j! W. V
        PayloadErrorsFieldName = "errors"+ w6 j) j" X/ C
    }). k: ~' ^. N2 b+ _: F7 ^
    .AddType&lt;PostType&gt;();
* H5 ]- R8 N. a  H$ V  ^</code></pre>: U/ V* q1 m' }5 }$ V
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>; m4 f) i3 o5 z: t8 ?( a+ T: V
<h2 id="验证">验证</h2>
8 Q; \; j/ u( x( S- N8 D<p>启动<code>Api</code>项目,调用接口:</p>
% }% A$ j. q: F7 n, \% K<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>1 v" V2 w% y. E1 Q% j+ H0 K' }3 V
<p>终端的日志输出如下:</p>
, z5 P9 @/ Y$ ?  e( |. B<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']8 F8 P7 \+ O1 J. J5 U& |/ R1 E
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title"), Y" `8 S, X( t' H
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);* a  B7 _5 g3 ^. _& I
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
9 ]3 k7 N8 u" [+ X1 H</code></pre>3 R9 B3 u# ?0 n* h8 G
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>% t) U  D  d, H7 E
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>' d+ X2 M3 d; z
<h2 id="总结">总结</h2>9 K( K8 Y- _% `5 U( Z; t  z* f% b
<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>
3 d: N" b% z1 o<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
( y$ I& K/ C6 u+ m
( h$ {, ]+ Y5 \# _- v$ j! r6 `
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-22 11:31 , Processed in 0.059257 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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