飞雪团队

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

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

[复制链接]

9171

主题

9259

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

- C( `6 z0 Q3 n8 }8 N<h2 id="系列导航">系列导航</h2>
  c2 B- u6 X# j! `4 y5 ^<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>( Q8 H. k; y; _+ ?. P9 e& T/ m
<h2 id="需求">需求</h2>
; I0 k0 b7 E5 K<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>; B" Q5 M( `; V) j  f4 ]; D; b4 e) s
<h2 id="思路">思路</h2>
; U) }- F0 {6 r7 }- S! o/ \<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
! G; _6 E, k4 r$ @+ ~- ^) n& G6 m<h2 id="实现">实现</h2>( ?% }1 n, H  j) e0 n% D$ B* p2 R4 [
<p>为了保持简单,我们先定义以下两个类型:</p>
( N5 }- Q6 O" y# o7 p$ V<pre><code class="language-c#">// 定义新增Post的参数: ?7 U) \& }# d: Q) v
public record AddPostInput(string Title, string Author);* \$ _$ `5 v# I! d! A

8 u7 ~9 F4 F1 b- l" T# [* ?// 定义新增Post的返回对象
! n/ b# T. W' Q# ^* C3 Ypublic record AddPostPayload(Post Post);
! {8 M1 \& F% z! i: @0 k</code></pre>. E$ ]% w& i0 I) W$ n0 q$ s
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
3 N; o& o7 ~& g4 r$ d8 t5 e" u<ul>
5 h$ y) b7 A% _2 I  _  c5 i. u<li><code>Mutation.cs</code></li>5 E6 }. T& M9 Q$ B, e4 a+ |
</ul>
' U+ B" k, X* p3 H" I! H: S<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
! k; e' ^' q0 t2 }: b7 `* i( G/ d+ E! z- o, L3 k/ ~5 p
public class Mutation
$ h- N- C- F# @' R4 }! j: [0 v{/ X# V0 Z7 D5 S/ P8 ?5 M4 ^0 W* V' Q
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
  k$ ^! W4 F, ]0 V2 ]5 t. j$ [    {* O% ^; v8 X/ D( a- ]
        return new AddPostPayload(await repository.AddAsync(new Post
- F- V1 I4 d8 y+ ]0 U8 A        {' w; ?, D+ @/ `0 I
            Title = input.Title,
0 d  a1 w; k* r2 f) h' [: B            Author = input.Author. `7 T0 U+ s* y) f, `+ ?
        }));! H8 w- b: l5 `) M5 s( W2 `
    }
! _2 I& i: e$ \, E}/ |* w% J$ n" {# U* V3 C2 r6 l0 ?
6 n& r; _0 t3 b& W
</code></pre>" `: b( ]# v' f$ U' O; I' C
<p>最后在注入服务的地方进行配置:</p>- t, c9 h. K$ @8 j- m) ~# r
<ul>2 u) V$ t0 e  N' {2 h5 T# N
<li><code>ProgramExtensions.cs</code></li>
# S, X! x( _! G6 K4 R" s</ul>* P: Y0 h. t7 E! o! v
<pre><code class="language-c#">builder.Services
" }8 M9 I8 ?' }+ z1 F    .AddGraphQLServer()2 m$ z* C0 O) K
    .SetPagingOptions(new PagingOptions
3 [0 L' K7 k6 J0 K7 j& n    {
% b& s8 Q, e  y5 |9 Y        MaxPageSize = 50,
" P: c8 \" R5 r6 |% s! S        IncludeTotalCount = true
5 |* p. C5 E) k( R7 F, s- s6 b' N    })$ Y+ L6 \, j; n8 _
    .AddFiltering()
: ^2 `$ K, x. \9 _6 O* B* p" c' i    .AddProjections()
+ g2 r1 }$ _" n/ d% |; Y: G: x    .AddSorting()
; S/ d3 T4 `9 M1 [. d    .AddQueryType&lt;Query&gt;()8 A( z' K1 H5 F. `) ~7 z
    .AddMutationType&lt;Mutation&gt;()
* t6 m' d& O8 M' Y5 {" b    .AddMutationConventions(new MutationConventionOptions
4 A$ e% k+ {1 E/ h' o    {3 ~$ v  m6 p' K) X; B* N  n$ G6 V
        ApplyToAllMutations = true,
7 @; Z$ C" f* W  U        InputArgumentName = "input",
+ B' J# f& [% b7 F        InputTypeNamePattern = "{MutationName}Input",
% k/ Q: K7 m2 U* B8 h5 h1 S        PayloadTypeNamePattern = "{MutationName}Payload",- [8 H6 k+ j3 z; ]& b
        PayloadErrorTypeNamePattern = "{MutationName}Error",
( G8 M6 O; q- V. q        PayloadErrorsFieldName = "errors"
- Y# h$ V7 H$ C  e    })+ `7 \7 H6 W# q9 g6 B) ~5 U
    .AddType&lt;PostType&gt;();% j* B# U! g* }9 p" g+ u
</code></pre>
# v8 z: k' d, r- i6 N* a0 x<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
4 `; _$ y/ x* ^' m$ G) v% k<h2 id="验证">验证</h2>
6 s' p* C# u% O7 d$ w' _<p>启动<code>Api</code>项目,调用接口:</p>6 B4 K) Z+ n4 X
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>( x' `9 m; y- V3 ~! l! ~
<p>终端的日志输出如下:</p>& B3 ]$ s  z5 J1 V3 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']/ ]. c; B$ b4 N, J
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title"): q, W( ^- G* d5 X, K: B+ g0 y8 Y
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
% z& i& {8 a- G: d2 ?+ B[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'+ \) V, o: E# L; ^* ^
</code></pre>; \. Y# s2 U$ m0 k1 w# T: ]
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
* J( `- j' u- B- c<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>; ^3 ~& o2 q  a; r! [8 b
<h2 id="总结">总结</h2>6 Z) \  ^. O$ H7 _* r, r
<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>
3 A" w$ i2 M  t6 i3 X<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>; N7 r$ T/ F/ t$ k
- J" Z% V. \1 c- @. e
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2026-9-2 23:53 , Processed in 0.308972 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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