飞雪团队

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

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

[复制链接]

8242

主题

8330

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

- ]3 `7 M1 p. E' ^<h2 id="系列导航">系列导航</h2>7 k1 r/ u) X! |# M8 |
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>) K2 b  x$ M. _1 f$ [+ ~' W
<h2 id="需求">需求</h2>
# ?* L! u5 W! K/ N<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
/ D" F  P$ t- c0 W* a3 n: V<h2 id="思路">思路</h2>
+ W, P. d7 k' C# U! M<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
; j* e0 @' w* N! F4 Q( _<h2 id="实现">实现</h2>4 `( i$ Q4 e& _* `% t( x
<p>为了保持简单,我们先定义以下两个类型:</p>
( e! u7 d' Z5 C( g2 n; f, k<pre><code class="language-c#">// 定义新增Post的参数
% v* Y* W8 e% J' ~& f4 E8 Qpublic record AddPostInput(string Title, string Author);2 T+ `' V; c! D( H+ P$ H
0 u) V1 H7 s+ n4 \2 Y4 b9 V+ ]! N
// 定义新增Post的返回对象
, s) A/ z2 v/ S  y0 `& Z. kpublic record AddPostPayload(Post Post);& I' O8 q4 G( r$ F
</code></pre>
& ]9 i% }: k% J5 O<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
* I4 Q  S4 [1 U" }# T- F<ul>
" \; u  a2 {9 [6 v<li><code>Mutation.cs</code></li>& y0 t  p4 H, s7 m, r
</ul>
. K+ t5 ^3 ]1 d<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;3 ^4 y! j3 m& b6 K# q
- v9 O5 Q) q+ ?7 v2 R8 U. W9 x* w
public class Mutation
# S3 E  ?8 A/ e1 {: z{0 e9 ^# ~0 k6 m" E6 N6 t0 k
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
  J& Y! a5 w' }9 K% T# _    {5 @, M$ U9 D5 p
        return new AddPostPayload(await repository.AddAsync(new Post  S- {. L! o' [; v! }
        {8 ], {- \/ Z6 ]8 _
            Title = input.Title,3 p* ?! P9 M$ \
            Author = input.Author
7 @! b3 z8 x# j* n0 ^        }));
/ ]" h6 m/ K8 Q( g9 }6 m, J    }/ I2 M9 l# s: |( V% p) Z) O% W
}2 W# q8 Y9 O2 h  ^5 U. Q

; [3 x  {/ Q+ ^  D# l& M& E( o</code></pre>
8 h  H! A+ p& U; S; ?8 Q<p>最后在注入服务的地方进行配置:</p>/ d* o0 L. G' f/ n; \* H
<ul>
- P( `1 H1 N/ ?<li><code>ProgramExtensions.cs</code></li>5 l4 T" K( {1 K- {8 w1 |; g: B; h
</ul>
7 @: T& Q. ]7 O. @8 Y2 m<pre><code class="language-c#">builder.Services2 r0 c/ T, O! U  n
    .AddGraphQLServer()1 A4 j; ]# b: q3 B/ A
    .SetPagingOptions(new PagingOptions
3 z' H+ C# D+ C3 y9 J" r7 v    {  b+ {) M; t$ A  f& j& t# V& g4 }
        MaxPageSize = 50,/ e+ M, {8 Q% q4 Y# ^5 h
        IncludeTotalCount = true
8 a0 }+ u  f! T  I    })( e, n3 T( u+ N% ~
    .AddFiltering()
# B9 X; F: x, o/ k    .AddProjections()$ s9 O& x4 t8 f' ]' d
    .AddSorting()% h; S+ D$ h9 ]
    .AddQueryType&lt;Query&gt;()
9 }+ ~/ @& i2 ]    .AddMutationType&lt;Mutation&gt;()
5 o/ T/ @% b' v. P' T& y    .AddMutationConventions(new MutationConventionOptions, z( ^' N5 f  ?$ _/ Y
    {
% m2 V: q+ m) ^/ C$ Z        ApplyToAllMutations = true,
! G. b# |+ {4 W2 G, m4 U) H        InputArgumentName = "input",2 R4 a% |* G4 }: f4 E( K. w
        InputTypeNamePattern = "{MutationName}Input",
, }) t" b9 d  W( c/ G* A9 B        PayloadTypeNamePattern = "{MutationName}Payload",4 z# b5 g- S% e9 K/ c
        PayloadErrorTypeNamePattern = "{MutationName}Error",' a( o0 N! U5 @3 E
        PayloadErrorsFieldName = "errors"6 g4 z, [" i7 k% q; o
    })( S3 ]4 c/ y/ x# p+ a+ i5 B! _
    .AddType&lt;PostType&gt;();
6 C! p6 h4 }0 g4 I$ z</code></pre>! p% u5 ^7 R4 [: U$ [
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
: ?6 W* j0 R3 u& Z& w' x<h2 id="验证">验证</h2>
' w2 J3 @' r7 P8 s<p>启动<code>Api</code>项目,调用接口:</p>
0 g  z  F, Q0 s" b0 ^4 e7 P6 J<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
2 ]. L' [9 _; i6 i<p>终端的日志输出如下:</p>
5 M* i4 D* @9 A! Q) u<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']7 F0 {' N+ M2 b4 L
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
/ ^  }4 f: }; L( rVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);/ k: E% D# `0 H8 [- e
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'0 d0 e  @7 t( [; m
</code></pre>
  P" E- V4 D4 o# M<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
2 g* q4 h- Q+ y<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
$ ~% I" l( l. @- s% p1 r<h2 id="总结">总结</h2>
$ B& ]+ y  J" o2 H8 T/ l6 Z, ^<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>
7 E* g8 K! S  u+ a! H3 l<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
* S& V1 B: J1 ~! F, y# I& P; }- G& J, v2 `# t" |
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2026-2-26 22:48 , Processed in 0.283089 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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