飞雪团队

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

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

[复制链接]

8134

主题

8222

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

" }. @7 n7 P% L6 E: `8 g. q<h2 id="系列导航">系列导航</h2>
/ v$ H, ~" V' S$ }7 r0 V$ o<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
& _8 U3 W5 b1 e# M8 s<h2 id="需求">需求</h2>/ _" }4 E% `) H$ V  ~. F; d
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>! J. I# ]# m+ c6 Q7 d9 T# ^
<h2 id="思路">思路</h2>
4 x' H! M: Z+ n; J" v<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
' `- g; i5 x: y  ]<h2 id="实现">实现</h2>
4 L$ J3 q. @2 q. J" F! J! _! ~<p>为了保持简单,我们先定义以下两个类型:</p>$ H: X1 B$ M" ?, A6 Z  p1 Q# U
<pre><code class="language-c#">// 定义新增Post的参数) w* _. \8 |+ p* j
public record AddPostInput(string Title, string Author);
! ]# Z  u3 Q. L/ A+ |6 {  v5 e! a- x: ]7 L$ m8 f* Q/ X
// 定义新增Post的返回对象
3 t" D" y, n% V$ j* k6 Ypublic record AddPostPayload(Post Post);
1 i; w9 o* v+ f' u3 i& W9 i* |</code></pre>
: _- B% t7 Q  z4 Y<p>新建<code>Mutation.cs</code>用来定义相关接口:</p># A" j* {8 l& c  ~  D
<ul>$ W7 V% H! O* a  A8 m% m
<li><code>Mutation.cs</code></li>
  C$ a- S6 [5 D) @3 p4 T* K% ?0 s3 e0 u- z</ul>" e8 X7 m6 F- r/ H- g! W9 Y
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
$ T, ^' U4 A7 `! `+ ]6 Y
: E. t) Q5 d- s5 b3 Npublic class Mutation7 a$ E( K; V. o& x2 ?" A0 l
{. {$ E: {) v7 R! |; [+ C
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)# L9 I: E- L' q" C5 K7 r
    {4 ^! v  a: V7 ~7 s6 f: U
        return new AddPostPayload(await repository.AddAsync(new Post  m& A: }  o* G4 z
        {: n3 M; k: h+ V- ~3 f: u. \0 H2 H
            Title = input.Title,
. Y& V4 e7 x4 n            Author = input.Author' I9 L' d$ M5 i8 t* w
        }));
  H# D9 z  X& v! d, t8 j4 |    }) e( `) [. B/ R1 D) s) ?1 |
}+ o4 n' X# t# H; k0 [5 D& `

2 B3 r* k" l( t3 }</code></pre>  d' b$ v8 r: `- O, t
<p>最后在注入服务的地方进行配置:</p>
' r- U' w* k0 Y$ \" j9 m<ul>8 ^) J: s3 g' L- \
<li><code>ProgramExtensions.cs</code></li>
6 n% E) l" v8 Z$ J/ ~4 |</ul>4 ~7 s% K+ i/ g3 g0 t% e% i" ~
<pre><code class="language-c#">builder.Services
0 Z  o6 [  @8 U( g  O( ^# ?( ?    .AddGraphQLServer()
( l8 w' _, w* v/ L8 ^    .SetPagingOptions(new PagingOptions
3 n- v; F6 g0 B7 W4 W7 n    {& o/ g6 B& @9 \
        MaxPageSize = 50,
3 H( o; R. m  j$ j0 l" Z1 g/ o        IncludeTotalCount = true
3 u/ I# D" @) C& I6 G4 h    })
4 T. H; v% F/ l  B$ s. N    .AddFiltering()
% E4 A: K2 e. I, l* ^    .AddProjections()9 V9 v& t8 k( S. a( F4 h. X" t3 K  A
    .AddSorting()+ n9 d6 u6 X+ ?( H
    .AddQueryType&lt;Query&gt;()
6 [: g/ `7 B4 J2 @/ n2 Z    .AddMutationType&lt;Mutation&gt;()
1 d" z+ c3 Z  d" Y5 g    .AddMutationConventions(new MutationConventionOptions
* T: X2 U( Z7 x& k& o$ I    {
! a3 t3 X8 |$ {+ c        ApplyToAllMutations = true,# ?. g- [* g& K" l
        InputArgumentName = "input",1 l* _# u9 l0 e$ ]3 x
        InputTypeNamePattern = "{MutationName}Input",
. P. ~0 n3 g" u0 X        PayloadTypeNamePattern = "{MutationName}Payload",
6 B' L- G" v- P3 e1 G6 |5 \0 B        PayloadErrorTypeNamePattern = "{MutationName}Error",
. T) ?7 M, c- ^) Y        PayloadErrorsFieldName = "errors"0 m1 d% M+ c. C/ X2 }* U
    })- h) ?9 S8 _2 d! g/ B" N! H
    .AddType&lt;PostType&gt;();
& w- I0 `$ b+ N; k7 F4 E! G/ D</code></pre>
! T4 ]: O- _/ S<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>8 w  t# C: L# h
<h2 id="验证">验证</h2>/ Z# c( C( I" a
<p>启动<code>Api</code>项目,调用接口:</p>
* Z0 ^4 I, x/ T<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
  S+ V  f% D# @' _+ {+ K<p>终端的日志输出如下:</p>& o. _7 {- X5 T- B' q/ \8 W
<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']
# m1 c5 W7 p+ ~$ x" L" qINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")2 u5 J# r) O8 R
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
2 r/ @+ W1 X' B  w[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'. j! w2 o: g5 q" M# W' h3 |
</code></pre>
* h, X- g) f& W. \2 g<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
* u% o+ u+ r7 j<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>3 W0 M7 U9 T* \) I  R( l
<h2 id="总结">总结</h2>
; Y8 e# ?: k* _) _# D<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>+ s0 W6 ]# a1 O% e4 }
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>" q/ i: Z$ d2 a* M+ ^
: X3 L6 n: o& ?4 ~: J1 D
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-27 16:40 , Processed in 0.072974 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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