飞雪团队

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

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

[复制链接]

9180

主题

9268

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

7 M  r1 j3 Z/ h) n: G7 v+ J<h2 id="系列导航">系列导航</h2>
5 Q/ T5 j# A5 E, V2 e1 V0 l<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
; `9 |1 A/ P3 E- t8 `0 h5 n/ ^1 _<h2 id="需求">需求</h2>+ h: ?% }3 A0 v& a# e* x" y
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
* q+ H( k% ?9 ?+ i<h2 id="思路">思路</h2>0 i% I/ X; W# {  m" R
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>8 N% f* Q. j; t3 K7 n
<h2 id="实现">实现</h2>4 {4 o2 M0 G3 r; O6 m6 Q
<p>为了保持简单,我们先定义以下两个类型:</p>5 h- ^4 g+ }/ W# l$ b2 y2 N
<pre><code class="language-c#">// 定义新增Post的参数2 B- ?$ Z+ J8 u0 H
public record AddPostInput(string Title, string Author);
6 g# N2 x/ |! [/ S/ D' ?. g
6 k: H% D/ b/ b( k// 定义新增Post的返回对象
" b: d, w% T5 s) B. g8 }public record AddPostPayload(Post Post);
  R) D1 _, O. H( ], H0 Y: d, W) S</code></pre>
  `7 t/ H3 q4 R$ z<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
+ }  j% M1 v! C& Z<ul>
9 t$ N5 |2 x  n8 K; x: o& |<li><code>Mutation.cs</code></li>' F, a: R0 t; q' x: S- e" G
</ul>9 {" i0 }3 h0 W! g( Y% M
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;3 b  t2 f/ r) M" L/ v3 h- x. D

% e# D3 v+ h7 {0 @# A3 Tpublic class Mutation! D: T. U1 v: Z' |& H
{
6 I9 U4 ?2 z. V1 C* ?( d7 m- r    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
0 x" g3 i0 s; I- ~1 P# L    {% R2 t9 {6 l9 g4 h9 p, {
        return new AddPostPayload(await repository.AddAsync(new Post
) R4 X3 C7 O3 C        {7 E* x' \8 N" s' g2 W, w
            Title = input.Title,( J2 x7 \! `4 a% P: l+ B. G; u
            Author = input.Author
2 n& Y$ s4 k5 _' J  `: h        }));& S/ L& W% M8 z0 M1 i  I  b/ Q
    }  X% J  a) L. G* t7 A
}
6 r! a8 U5 j/ c) _9 U! A- x+ [- |! t" p" x& D! A& s
</code></pre>% B+ o! g" B( t# a
<p>最后在注入服务的地方进行配置:</p>4 a2 J8 n8 O7 z3 s- I* @8 M+ o
<ul>
$ x5 `2 x2 \0 k7 ~" p$ i3 i<li><code>ProgramExtensions.cs</code></li>0 n. B- l+ p' R# x* y" r  D5 Q5 L
</ul>
( j: v- m4 p4 D. V  M" Z2 t<pre><code class="language-c#">builder.Services) a: _, ^8 n: k7 C( }; E% j
    .AddGraphQLServer()6 d) i& f6 E. a! c
    .SetPagingOptions(new PagingOptions
1 E% g( v6 [: c+ X1 z0 g2 l: n: c    {
, \% Y; N  S( p: S2 o; ]# {# j        MaxPageSize = 50,. i, K7 z! M9 q8 ~" D, W+ ]
        IncludeTotalCount = true
7 r* z. Y# V2 ^) u    })
5 J2 |2 H2 `0 f* Y# m9 L3 B7 m    .AddFiltering()
5 @. d/ ~3 z5 H5 y) O$ N2 @+ l0 ~    .AddProjections()
' d! @4 ?% y0 S    .AddSorting()$ Q1 H; i1 _$ R' T8 e) G
    .AddQueryType&lt;Query&gt;()
& J4 {) \$ Q* i2 o8 i8 s9 j; o    .AddMutationType&lt;Mutation&gt;()
# i8 v7 d( ^0 u. m: S& {2 Q3 e7 M! U" e+ W    .AddMutationConventions(new MutationConventionOptions
4 {, H7 X  D$ n3 |+ v# q    {
2 B" ^# d( v& q. s        ApplyToAllMutations = true,# M- g& S0 e# s, G1 f9 \, {
        InputArgumentName = "input",, |& n+ Z; ~1 Q7 r8 U" q
        InputTypeNamePattern = "{MutationName}Input",. @4 G" j4 i7 @
        PayloadTypeNamePattern = "{MutationName}Payload",
7 g! Q" w1 j5 a        PayloadErrorTypeNamePattern = "{MutationName}Error",* L5 m0 R! G4 D4 f
        PayloadErrorsFieldName = "errors"
+ K+ H% o' d, ]5 D    }), v. B6 R$ _& J* Q
    .AddType&lt;PostType&gt;();( X) e$ S0 p0 V. h
</code></pre>% Y' {$ W& G% M3 ?6 @2 I6 U( [
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
* g1 f) T( W6 G, q# e; x/ x/ M<h2 id="验证">验证</h2>4 h0 z8 m8 {9 K9 a/ ~8 J
<p>启动<code>Api</code>项目,调用接口:</p>
1 Z/ T4 X+ u$ \8 G) Y2 B' j<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>2 L! q6 E/ q: U9 _4 k" V5 t
<p>终端的日志输出如下:</p>3 I  K! i: h  E3 A
<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']. V- N9 H% q8 @) P
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
! \9 k0 O2 ~. _6 ^$ nVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);- a; r7 F- O5 h: s; d6 }
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
( D& C. ]& e& }  }. F$ i2 h</code></pre>
/ X! W& e0 t( H7 _! a) \7 C( [<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
9 h6 g; o* Z9 b& c<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>) `& W' F+ y0 A) `
<h2 id="总结">总结</h2># x6 Z; s* a9 _3 Y/ N. U  q7 J! W& _/ u
<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>
: Y. H, h  l" S0 V% Y& g, C8 j<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>5 M& k8 k8 k- v. `, L+ x+ R
- q' l4 \/ E# N" |) O; X
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2026-9-9 11:47 , Processed in 0.060510 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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