飞雪团队

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

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

[复制链接]

8292

主题

8380

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

/ Y2 D; G. `% c, r/ w+ G0 _$ Z<h2 id="系列导航">系列导航</h2>
# u! x/ I$ s. j3 O( |) P  O<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>5 h( y( ^0 I; |
<h2 id="需求">需求</h2>
2 z/ U- R- k0 R( v  }$ |<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>1 y3 X. B' a# [
<h2 id="思路">思路</h2>
( p3 M  H) f# {, M3 H  |<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>; C9 E. i) {. z6 T
<h2 id="实现">实现</h2>
3 M- \6 d  [' r* w1 C<p>为了保持简单,我们先定义以下两个类型:</p>
. O! z! D  b7 K. _+ O1 z1 O( c<pre><code class="language-c#">// 定义新增Post的参数9 |+ @$ T4 y3 K* ]2 l5 i) z8 k" |
public record AddPostInput(string Title, string Author);
, m0 Z% n% P, |- i7 S7 D" @8 ?, P, j* N5 }" `
// 定义新增Post的返回对象
8 E! c/ E7 n! @3 j, E% Gpublic record AddPostPayload(Post Post);
0 }# O$ }5 c. d</code></pre>: }, v0 `  s9 k- \" F* d7 u
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>4 _8 i7 x. ?1 O: R* b4 }
<ul>
( [) k' ^  [% C) ?6 W" W; W* [( {7 R; W/ M<li><code>Mutation.cs</code></li>
$ ]- B, a9 t0 C0 A! c5 {, J& ?</ul>
% g, A2 h9 b+ E7 g$ m( ]8 M<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
* r9 ?: F  a; [1 Q! L5 K3 _& q( `
public class Mutation
4 U! Q! I$ i  i5 G{0 W4 j1 ?0 ]6 n$ @' ~
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
- m: D8 x! Y9 L+ n: a1 M    {" M% r7 {; R1 I3 l
        return new AddPostPayload(await repository.AddAsync(new Post: n+ p" H" R, Z5 S0 S
        {
( w3 F3 ^! h; d, G- y            Title = input.Title,+ t! R0 Y( g3 ~3 w: i! n  y: p
            Author = input.Author
  P8 p9 }: c0 N; A0 ?4 z6 Z$ y        }));- M* x* U. B: H. K
    }! P$ D8 {' Q1 s8 h; e1 D
}/ o1 H7 J) q3 j' |9 q7 K! v2 M

( f/ E! U8 S: q6 R& C</code></pre>
3 n5 k* W5 [6 G- D. o<p>最后在注入服务的地方进行配置:</p>
- e: M1 P+ y0 g5 a<ul>
1 r- ^$ V* N" v& B8 ~<li><code>ProgramExtensions.cs</code></li>
1 _- o3 }4 m2 x  R4 |</ul># g* ]1 P6 v! c
<pre><code class="language-c#">builder.Services3 `2 b  y; k/ ~
    .AddGraphQLServer()
* A8 C! W5 V  E! I& @    .SetPagingOptions(new PagingOptions
4 D8 j4 t) p" p/ G5 E- T    {% F3 g3 T  @& o$ A& v: E
        MaxPageSize = 50,
. U) g5 s5 K' o/ P( m        IncludeTotalCount = true8 d( |' ^2 O1 A  T: s& B$ Y9 Y
    })
( t5 W7 O9 W  w3 o9 v( B    .AddFiltering()
2 z! d' O; ?7 ~6 f2 d8 t    .AddProjections()' K9 _: \/ N# w
    .AddSorting()
9 e, f; ^  k& F" a8 A    .AddQueryType&lt;Query&gt;()
2 K. S& L4 T8 Q3 {& ?, B    .AddMutationType&lt;Mutation&gt;()
2 w% v/ a+ ~( @+ J    .AddMutationConventions(new MutationConventionOptions/ R7 e$ Q& C  Y" j# T2 F
    {* w/ q/ U8 C! d% f
        ApplyToAllMutations = true,' L% _3 Q5 d" p# V5 T
        InputArgumentName = "input",
7 @# I( l, T" ~) ^9 q1 T2 l6 Y/ f        InputTypeNamePattern = "{MutationName}Input",, o5 m, W7 S) y2 w
        PayloadTypeNamePattern = "{MutationName}Payload",
! E9 {9 U& E3 F( r        PayloadErrorTypeNamePattern = "{MutationName}Error",) D: D( `8 N: {2 D: b) F( T
        PayloadErrorsFieldName = "errors"
0 i5 ]2 [! E. y    })0 q% _2 k# {4 q+ Q! l, ]  P6 I
    .AddType&lt;PostType&gt;();
% w2 P, I: I; S</code></pre>" u. E2 p+ e0 I. [: [
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
$ ?) N) {9 e$ ~) {) |9 Z5 K<h2 id="验证">验证</h2>
. B- u- q/ }& \$ f) d* @<p>启动<code>Api</code>项目,调用接口:</p>. i+ [. w, R! k+ N1 C+ B
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
( y1 I; d& k2 R# w' b<p>终端的日志输出如下:</p>
% ~% B) ^% P! \, X<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']# n* a- m; Y3 M9 J
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title"); \6 M$ c9 i( |
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);6 f" N( \) \7 O  l
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
* T& i( p" K4 S7 q8 j</code></pre>$ t' Z! |5 N3 J( I0 o
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p># p3 |/ F4 j' O& `8 v$ Y" z' V5 G
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
3 h  v+ p2 Z' y- F) o% f5 N2 [7 e<h2 id="总结">总结</h2>
0 O. b& d" a6 j# E. S& c7 [) @  ]<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>) X9 |# X. ^) o  F7 W5 t5 Y0 W
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>, W- v/ Y% z# O' L
! l, s- f( T& Y
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2026-2-28 14:40 , Processed in 0.105240 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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