飞雪团队

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

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

[复制链接]

7928

主题

8016

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

/ ?3 e& E% E. ~5 m2 E<h2 id="系列导航">系列导航</h2>8 W8 M' U: M3 s, C6 b$ }) E" Q( w
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>7 D. _  e6 t0 c, u8 f
<h2 id="需求">需求</h2>
" W. J- u$ x: b0 ~. Y6 i<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>, R/ e( s" G# P5 G+ j$ Q
<h2 id="思路">思路</h2>
7 A+ t) A4 i4 k<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>' N- v# D5 u" l: R9 ~
<h2 id="实现">实现</h2>
. a6 K4 R3 l8 a% r% ~' N2 P<p>为了保持简单,我们先定义以下两个类型:</p>
' z: o1 {+ t$ v<pre><code class="language-c#">// 定义新增Post的参数1 v1 L" ~  p9 M" x* ?! x7 Z$ ]
public record AddPostInput(string Title, string Author);$ ?- T, z+ A! E9 d

9 O$ N7 j0 m" ?- X7 h8 {. R- g2 y// 定义新增Post的返回对象
& ?/ ]+ @4 N4 V' k. r+ F6 C5 Epublic record AddPostPayload(Post Post);' J, \: u2 I3 i* B$ ~
</code></pre>
$ z; p. Z; ?+ d- j) h: |& P<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
% I1 B/ b6 ?/ I% n<ul>
! F/ J# f9 A( p<li><code>Mutation.cs</code></li>
% [! k! |$ v  C8 {</ul>
  q; {) t. t. ^" `<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
4 a4 L- @6 z6 U# V* c( `* u. X. l4 l: t, }6 K8 a% Y( k6 `
public class Mutation
" y( q' j! q1 h4 S6 M- X$ K{4 m: c3 g2 I" N0 ]* U
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
1 D2 `( P5 `5 X5 i! \    {. [+ t6 E5 g4 s
        return new AddPostPayload(await repository.AddAsync(new Post
* A$ Y7 O9 ]& V# X        {
$ N$ D% f; L& J& _+ Q# ?            Title = input.Title,  W* W5 }$ z6 y1 z% m3 P, r5 f
            Author = input.Author
) l' K7 N1 q1 i$ l& }, Y  o& Q+ {- r        }));$ {$ C8 i' ?, i5 c* c+ e' G
    }4 ?; `- b  S8 N! n. i" q) t+ `
}, @( k4 M1 F/ w, ~1 l1 W" O
% @; E8 ?6 j8 v7 t1 c0 c; `
</code></pre>
7 c3 m# u2 d( G<p>最后在注入服务的地方进行配置:</p>
8 x; P+ m- n* `: w<ul>
, l+ d$ X6 N. a$ M2 ?. E, {<li><code>ProgramExtensions.cs</code></li>
- e; r& V) v. E# A0 S$ h  G1 c</ul>  h5 J5 c" b6 e
<pre><code class="language-c#">builder.Services
6 y$ V$ ^4 n' s% C! Z' H    .AddGraphQLServer()
8 [5 s6 N; [0 \) k" r) ^3 z1 \! j    .SetPagingOptions(new PagingOptions
" i8 o, U8 X8 V1 R6 {0 G4 K2 m    {
8 J6 W' z( B% ~% g        MaxPageSize = 50,
0 ~, U" ~, M" v# W! @        IncludeTotalCount = true# R) j! K6 R# Q0 R  C, X- H9 y& V
    })
" F5 e& M% `* F: _' f. z    .AddFiltering()
. t0 h9 W8 z9 S, p    .AddProjections()
( L" {, }2 ~) k1 ~" O5 k' \    .AddSorting()
0 M; f  j, R0 Q* P    .AddQueryType&lt;Query&gt;(). f$ z& i, j; ~
    .AddMutationType&lt;Mutation&gt;()# s6 W5 o$ w* E6 E
    .AddMutationConventions(new MutationConventionOptions6 R% B: W/ H: @$ M
    {
8 H9 i% z+ p5 p* P# N1 J* w# K        ApplyToAllMutations = true,8 i5 i& A8 e1 Q3 ~9 T, q) r
        InputArgumentName = "input",, X8 z7 M, U7 |) Q0 p
        InputTypeNamePattern = "{MutationName}Input",# X# @/ M! W# z# m& M+ \
        PayloadTypeNamePattern = "{MutationName}Payload",
& o1 }7 x, f6 A        PayloadErrorTypeNamePattern = "{MutationName}Error",
! y1 u  q& a( N( W/ c( A/ q        PayloadErrorsFieldName = "errors"" @+ t$ d4 R0 u! O2 ~
    })
7 d2 ~9 i, Z- I) v0 r  Z    .AddType&lt;PostType&gt;();0 e. R. u5 m& m2 e/ g0 ?7 {
</code></pre>
! j3 y' _- \' \8 L- O<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>  n: G# D& R& U4 z5 c) ?
<h2 id="验证">验证</h2>
" M! @% g: t5 [8 @) Y4 k1 v<p>启动<code>Api</code>项目,调用接口:</p>) i7 Q2 a, v# u+ R0 c5 |
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
3 u  l4 O# c' R; N# I! u<p>终端的日志输出如下:</p>
: C! `' P7 R; f6 A  L( _+ P5 b<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 @! j& b) U6 ^& a) Y; o% W
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")1 `& ^; J/ W+ t, l' F  B5 k" e! z
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);, y6 C) y* }! F  P0 r: N
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'* @# `  z( n6 a# ~& M7 X4 F
</code></pre>, T5 r* Q6 ~/ n
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
6 O( k- J+ F! `<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>; S( M* P. J/ C- B
<h2 id="总结">总结</h2>$ h5 U1 N+ H9 z0 l8 {0 [
<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>7 M1 `( @" ^; m# d& k
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>: Q! q; y8 C. c0 E" a+ f$ u$ W
. q4 L* [9 D. R
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

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

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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