飞雪团队

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

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

[复制链接]

7900

主题

7988

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26030
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
) Q5 ?2 {0 G8 m) l& [
<h2 id="系列导航">系列导航</h2>) Y' x) i* a" [
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>5 E4 `$ \$ c+ e6 o2 \! s# Q: H
<h2 id="需求">需求</h2>7 k4 w* Y2 H; c1 {9 v* b
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
0 |; N9 o' S% Z<h2 id="思路">思路</h2>
, R1 ~9 q1 w& B! c<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
7 F) y7 {; M( \) J<h2 id="实现">实现</h2>! K9 R4 G1 w6 s
<p>为了保持简单,我们先定义以下两个类型:</p>
( Y7 i4 N, {; x! `# w  U# @<pre><code class="language-c#">// 定义新增Post的参数
; p$ `/ q: p/ r) p4 _2 |5 z! spublic record AddPostInput(string Title, string Author);
6 I% Z, y; y5 z& c
, c% k' O. O  T2 V: F# {// 定义新增Post的返回对象$ ?' Z7 X) h- r8 R3 d8 Y5 l
public record AddPostPayload(Post Post);
4 I' p5 Y" @1 O1 O: _3 e</code></pre>
! v& E/ M: G$ v1 S<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
0 M4 c1 ]8 p# L( O* i! Z4 b$ O9 z<ul>
' o8 \+ L5 g( L5 W" p# }& o<li><code>Mutation.cs</code></li>+ x- b! G, F- j; G
</ul>( w- i5 U7 o5 O6 h$ U! ]) D9 T
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;: I* N% }. w4 B0 G' X# K- r6 F
! _* A# J3 T5 ~
public class Mutation. y/ n# O$ e5 A; v
{4 }2 e  s( N$ }8 d" o
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)- y. t2 w8 o( ~' Z) b7 [" f/ }0 Z
    {
8 S' D5 f! ~* Q        return new AddPostPayload(await repository.AddAsync(new Post4 ~6 }- L, y5 G, \; U9 O6 y. h( y
        {- \; z" @% W- Z& E
            Title = input.Title,
7 m6 n& C3 Q2 t. e            Author = input.Author
) d# ]; h& A. i  Z        }));( W  i% K# ?- i* w
    }
, C% F% M/ M- n4 i; b0 ?}7 Z* H2 g0 d. v3 c

/ D$ r* Q* a: f& |8 Z! K- b1 {) c</code></pre>! E9 j0 b/ p) [& d+ g9 \
<p>最后在注入服务的地方进行配置:</p>8 D" f, A* Y7 t! o2 ]
<ul>; Z& A+ _; R# e8 ~
<li><code>ProgramExtensions.cs</code></li>/ c  c8 h' I7 G6 A2 P/ o! h
</ul>
1 b; g$ u2 M0 c<pre><code class="language-c#">builder.Services3 h# @3 i, G: u# P' b
    .AddGraphQLServer()3 ~$ L$ [! W4 @" Y- o7 L$ z
    .SetPagingOptions(new PagingOptions0 g* S& U5 O- C4 w: i: A
    {, u- N" s* V" P6 V" p; R
        MaxPageSize = 50,
( b& K5 F# P2 y0 G# T) X' p        IncludeTotalCount = true. L9 s' g# b4 q' O7 B# k
    })& v9 A& q- a$ s* S7 X% H
    .AddFiltering()* d# K6 \: O( M* f" i
    .AddProjections()3 u& F9 h  r) `% ^3 {9 J1 X/ |
    .AddSorting()
  V; y5 z; C0 \. @  w1 d' \4 h, [* E* Y    .AddQueryType&lt;Query&gt;()! [# y  A. `4 t& ^; Q
    .AddMutationType&lt;Mutation&gt;()
9 c; h# n- F( Y1 @  X) g2 ?+ s    .AddMutationConventions(new MutationConventionOptions
# e# u/ Q. c1 y  ?( Z    {
- F, s) e6 ~% V        ApplyToAllMutations = true,$ L% @, z* a1 E2 n/ R+ Z# W1 @
        InputArgumentName = "input",9 Q" `9 X6 c* r8 r9 \& D
        InputTypeNamePattern = "{MutationName}Input",. S- b0 I- D2 }, a: L
        PayloadTypeNamePattern = "{MutationName}Payload",
$ _9 Y9 x% V# s5 X4 s/ f        PayloadErrorTypeNamePattern = "{MutationName}Error",
4 I5 [' q  U; T( H        PayloadErrorsFieldName = "errors"
: U2 I& m2 [5 V* L. G& B' ^) X: R    }); D. M4 x3 G/ U0 }! E; K5 \2 v" D
    .AddType&lt;PostType&gt;();- r4 f8 A7 h" [# A
</code></pre>
2 ~) p8 \( X' W  v/ O<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
! j) @8 J- k  D5 G. @0 q) d<h2 id="验证">验证</h2>
/ Q4 P% d9 n7 C9 j' s  ?2 C<p>启动<code>Api</code>项目,调用接口:</p>
# U  Z9 ~, b, S$ E# K<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
6 {+ v$ Q. t- p- Y# s3 S<p>终端的日志输出如下:</p>
. {+ E/ m3 a5 R$ Y* W) b+ Y! T, m<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']
4 ^5 n  i* X3 q, s: i% aINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")5 E: Y) w3 q( i# u- `: `
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);4 L/ y6 i* x! p/ E6 `: T" T; B
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'+ Z+ k/ p% R! u: K, Y+ i8 f  ~: U
</code></pre>! R: @4 K$ @3 f& _; S* W- x
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
% M3 ~. e6 @0 [/ [- m- ?4 |) v: O/ H<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>" A( }& p4 G. d$ O9 f' ^2 n; ^
<h2 id="总结">总结</h2>
1 X# a) C; k! P<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>( c/ x9 m  g5 ^9 F) h: X: g7 H
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
$ ~/ Y5 \+ k0 x' q7 f1 o0 V
7 s: b- M: m; p  \6 G9 q
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-21 02:58 , Processed in 0.068757 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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