飞雪团队

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

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

[复制链接]

8131

主题

8219

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26723
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
+ E0 O, {8 B/ |9 K$ K$ b4 Y, h  Z" g
<h2 id="系列导航">系列导航</h2>) E. p: `: k8 j) Y% X. |& j
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
: T  y7 n( q6 O, ?  m<h2 id="需求">需求</h2>
$ a5 |1 M0 m. S<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>4 U- k. p' f) v9 V0 y1 P4 c! @
<h2 id="思路">思路</h2>: H7 p1 A( K* M" S
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>1 V: Z1 N5 U4 ?9 G! b8 s
<h2 id="实现">实现</h2>
- Y' q/ H7 K: J8 l& Z( @<p>为了保持简单,我们先定义以下两个类型:</p>6 o) H( B9 t7 {% Y+ f. c# g5 {
<pre><code class="language-c#">// 定义新增Post的参数2 v6 }+ ^' U/ d$ L1 h0 f
public record AddPostInput(string Title, string Author);# v3 ?7 s% _6 z- A2 b) @* H* A! r0 t

, B9 C( M  x0 U0 J/ L+ `7 [; |7 j// 定义新增Post的返回对象0 d$ r# O$ m& R+ c) v
public record AddPostPayload(Post Post);  _4 k, S+ y( q- F
</code></pre>
2 V. N6 h+ h6 U6 W<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>+ N; M# t/ ~: G
<ul>
0 l0 g2 H2 R. O- ]<li><code>Mutation.cs</code></li>
7 X, t3 }) J* p  S* r</ul>7 y" A! }. F& S# n/ D- H+ i6 @
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
* v) Y+ ~5 e! b! I9 u$ e: B% B# R3 [$ B( ]
public class Mutation9 f5 N9 Y  W8 ]% |- s
{5 s6 P1 m; e! U, S9 `7 E  q$ K2 I
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)$ d# d4 m% b7 W  k
    {- Y- h% u5 a. i6 c
        return new AddPostPayload(await repository.AddAsync(new Post
) u# o. [5 L! O3 H        {
4 S( o, E0 l' }            Title = input.Title,0 G" |! k, h7 B5 ?
            Author = input.Author
- p0 i% q; q5 S& @9 e        }));" ]0 l7 u% }  |) N% v
    }8 E2 M: J% d5 w* U; T
}
! C3 h, O; y* o, ]1 C. x- y/ a8 Q- X. c5 ]: ~% D
</code></pre>
+ D9 k7 Y2 \. T* q<p>最后在注入服务的地方进行配置:</p>
3 ?1 ^; {3 G  a2 f4 A! w<ul>! y: s% k4 d" a, D) L- m( k
<li><code>ProgramExtensions.cs</code></li>  O# x/ z; K0 e/ T( R+ c
</ul>* L+ _, [2 q4 x: `5 c1 r4 _- h# \+ h
<pre><code class="language-c#">builder.Services
, o; x" Q3 P$ k# N% E* u* `    .AddGraphQLServer()& K( m6 S* c& b1 t# y
    .SetPagingOptions(new PagingOptions
% \9 n6 Y4 L9 P- s4 X# Y! V. b( ~) z    {
1 \2 u( V9 \5 a6 W        MaxPageSize = 50,
' r/ @% v' R/ y2 |% `        IncludeTotalCount = true) @* W' K+ g  \! A6 j8 q! Y& O
    })
$ ^5 |, t8 ^) E: b( u    .AddFiltering()
9 R3 i0 C" v& n( ]' f    .AddProjections()
$ V% C' ?2 Q6 E# G! k5 b: K    .AddSorting()
$ c+ c# z  K$ e# ^" B    .AddQueryType&lt;Query&gt;()
; N0 Z+ I0 T( J    .AddMutationType&lt;Mutation&gt;()
% p- M, Z, r: \- a+ t' k' N, D    .AddMutationConventions(new MutationConventionOptions
1 j+ o. V% Q9 ]& I$ w, |' f+ ]    {
# B4 h: @( G; Z$ [5 H        ApplyToAllMutations = true,% v  t4 e/ h/ k3 n4 y) k- n3 `  D
        InputArgumentName = "input",
  t  a  \# {- Z, |        InputTypeNamePattern = "{MutationName}Input",
" B$ t  a3 @, G: Q        PayloadTypeNamePattern = "{MutationName}Payload",
* T" g4 |# |7 o5 i        PayloadErrorTypeNamePattern = "{MutationName}Error",1 e* Y+ ^' V2 r8 ], @/ X
        PayloadErrorsFieldName = "errors"* a) l6 h  G6 A2 {' o) {# e
    })( c7 x: {- M) L3 O# F
    .AddType&lt;PostType&gt;();
$ @* @2 ?! h7 ]+ V  }; {</code></pre>
% l- j) N/ S7 p, A* B. o% e<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
$ c7 R  E" ]" ]<h2 id="验证">验证</h2>
3 \1 F# s5 n4 q9 D) Y- @) k7 {- E<p>启动<code>Api</code>项目,调用接口:</p>$ G5 p9 b0 t+ B8 C5 e
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
6 v8 ]  f. N2 S( v- d<p>终端的日志输出如下:</p>- Q: M+ m8 M9 ^# v0 R
<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']
9 `/ B1 K) b* x. U) R5 _INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
( R% A" a9 x" ~VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);# V! ?! N" p, \5 x3 e$ N4 d
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
& \0 j& g& g7 J* k0 E: p- `</code></pre>
0 L+ t+ T  V% I+ X" g2 m1 e<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
+ c3 Z) U% m) U, x: ?- \# T<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
; c: x! c  Q0 a; F- Y1 L<h2 id="总结">总结</h2>
8 E, e9 o: e, H, \  w<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>4 J% Q( h' J6 d" w9 Q! g" R
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
2 ?9 h2 R# t, S/ i" k
% H( y4 O# o, ^2 l8 {, r. ^& B  j
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-27 06:53 , Processed in 0.214489 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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