飞雪团队

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

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

[复制链接]

4137

主题

4225

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

6 R/ K8 J! m% P. i<h2 id="系列导航">系列导航</h2>, }2 P8 o9 t5 g& b# a, O) i
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
# `3 M$ |1 o4 v9 t! x<h2 id="需求">需求</h2>7 z0 J# J! [+ w7 V; l, |- ?( G5 F
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
3 D! h0 ?. A* `3 |8 Z! u0 X  u2 L<h2 id="思路">思路</h2>
) B: k" b) P2 B. W3 ?" j<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>$ e. b* p# ]% P# m, B; g
<h2 id="实现">实现</h2>, k, M8 C( T( a8 r) I4 t
<p>为了保持简单,我们先定义以下两个类型:</p>$ O8 D/ }8 N2 y; p: f
<pre><code class="language-c#">// 定义新增Post的参数$ n4 |. G0 i9 m2 ]2 k5 f- p
public record AddPostInput(string Title, string Author);
$ U5 ]6 |- X1 ~
4 @% i% J: \5 B// 定义新增Post的返回对象& X/ i2 L; B! V$ ]0 G, L
public record AddPostPayload(Post Post);
1 u; g- V9 X3 [4 r</code></pre>3 A* c4 b% l. k9 A9 [+ [! O
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>3 w$ b0 d& H, z& D, l$ P( b' g
<ul>; Z, s; i- s/ P! v$ `8 j
<li><code>Mutation.cs</code></li>& R+ I& J8 N* ]/ I3 P0 l& \; }
</ul>+ }# Q$ G" A) j% J( e+ _' k: B
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
: G; R: J( T  U+ e: S, M7 c: u- u% Y/ T9 T5 C* P! n
public class Mutation
8 b! |. i# B+ P" H{5 |# F& Q( C% `" i
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
2 f0 e/ T  Q0 i3 y! ^1 _/ T    {2 `5 l0 ?" b% i/ Q7 j
        return new AddPostPayload(await repository.AddAsync(new Post
' m7 P2 X9 p/ J* p6 c$ R        {: U( B" m' t  V/ `6 C2 ]. v  W- r
            Title = input.Title,
8 M9 E5 Q) N) {- o; f            Author = input.Author0 n9 L4 c6 \1 R$ _- d0 [" c! z
        }));
& p7 E( d8 K5 Y, m6 u, Z2 t    }
  Q: v6 B$ N5 g3 C1 R}8 }8 O+ m4 j* S# _. H" p
* S4 e; K7 y; t( t8 G/ z
</code></pre>
; }5 m& D4 R5 R( q- ^& P5 `9 o* ^. B<p>最后在注入服务的地方进行配置:</p>. |$ i8 \+ g6 `; b- O
<ul>1 o, g3 S/ B" ~" s+ s
<li><code>ProgramExtensions.cs</code></li>
- M9 ~* o( P+ {$ n& C- e</ul>
( f* X, q+ X" H  I4 |<pre><code class="language-c#">builder.Services
/ ^) B* n6 |0 ]8 _" }( M    .AddGraphQLServer()
6 a7 W. Z, x& W2 s! o    .SetPagingOptions(new PagingOptions* c7 s" G; P, S2 M+ ?
    {
6 I5 E! b  V- E! ~( I( x6 K        MaxPageSize = 50,( u: _) g+ W7 V
        IncludeTotalCount = true; V% ?, L& p# c' B1 G
    })
9 {/ {, ^  H2 Y' }3 A    .AddFiltering()
7 L# I: e7 S- D; ^3 ?, w    .AddProjections()
+ L4 a" M& c& ^. L5 A1 [0 }    .AddSorting()- q! h0 T0 Z6 E3 w
    .AddQueryType&lt;Query&gt;()
8 ~4 u3 `- F- O+ w& C    .AddMutationType&lt;Mutation&gt;()' o7 A- @6 V6 p; x
    .AddMutationConventions(new MutationConventionOptions* O3 Q- ~( n( D
    {8 ^- O3 d0 J/ N, v& u7 J8 Q5 d
        ApplyToAllMutations = true,/ A8 W: A: v  @6 {# i
        InputArgumentName = "input",$ ]. p9 v! S4 A* q$ s) x
        InputTypeNamePattern = "{MutationName}Input",
# ]+ h' u; Z) ^9 @4 {, x        PayloadTypeNamePattern = "{MutationName}Payload",( z3 o$ b  b" ^5 Y' r! R+ I( X# G# v* E
        PayloadErrorTypeNamePattern = "{MutationName}Error",9 a( x4 u3 Y- V
        PayloadErrorsFieldName = "errors"
. ~$ C5 r) N" T' ?2 C0 A    }), l9 J2 {3 Y2 g7 E* ]
    .AddType&lt;PostType&gt;();/ s: M. z1 \+ L# M' [! k" _- O
</code></pre>: k: |1 c6 @) n. j5 m- O
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
4 v$ O, Z% R9 k$ V<h2 id="验证">验证</h2>
+ B7 T1 c/ T) K% U5 z  {<p>启动<code>Api</code>项目,调用接口:</p>) d" ?; g4 d, G& i
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
8 g1 d, [" X" I! Z, e1 B<p>终端的日志输出如下:</p>1 }; b: D! Y0 r5 c
<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']
* ?# `  `1 |+ }8 e8 Y1 J# W" tINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
2 m# k# S/ ^& l8 [) EVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);3 I1 g* B, ?; b* V  `) S
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
, h" \3 A2 A/ q/ X% i& e$ f& ?% N</code></pre>
- w# u8 b( V/ p# u) c<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
5 c' R# @, m4 g: H% a<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>9 H2 n1 q& z6 a, q! F0 n! Z
<h2 id="总结">总结</h2>
, o) O/ Y) a% ]% K( _, j<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>8 o4 b# D' n  Z% I- ~9 ^+ ]1 T3 ~
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>1 \, k: `+ w9 }/ O. p) v- r

" z- k" k$ }1 q7 A! k+ [/ [% x" S
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2024-4-29 12:42 , Processed in 0.061519 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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