飞雪团队

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

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

[复制链接]

8560

主题

8648

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
28010
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
$ B! |6 {+ \' s1 r8 }
<h2 id="系列导航">系列导航</h2>4 K* o& f+ |3 T! x( a1 w' v8 ]+ ]
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
4 L; w- O7 u# B- \  O<h2 id="需求">需求</h2>9 K; e/ v) Z: s7 A4 y5 Z
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>5 J# q* P' i3 u1 V' l
<h2 id="思路">思路</h2>1 X$ U: p2 R) Z# [
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
+ a: L1 P4 C5 P& a  h7 m1 p- H<h2 id="实现">实现</h2>; K7 b" X7 L3 v! u3 L
<p>为了保持简单,我们先定义以下两个类型:</p>
$ S/ I+ D7 M. Q! M6 ?+ C, |8 E<pre><code class="language-c#">// 定义新增Post的参数
. F4 o# n. ?# U' {. a, Zpublic record AddPostInput(string Title, string Author);
7 C/ r3 J/ ^" D/ {. l) |
5 j0 S; D4 s( u6 p// 定义新增Post的返回对象, ^  ^  s6 Q0 S$ d' ?2 t6 j1 x
public record AddPostPayload(Post Post);; _; a+ `, Y* U1 L
</code></pre>  X! [# D% T' O
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
$ C# ]0 D! s* e( c: M<ul>& Y: `  u, u$ y- ^2 V
<li><code>Mutation.cs</code></li>
* b  b! h; l& ^2 z% u, b+ N</ul>
+ _5 D2 A2 G9 F7 ]8 ?<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;) t/ t$ t- T+ Q- H
3 h3 E% T% n4 L! i! ~! |
public class Mutation
: U% y5 B: i8 y! J8 }* V4 z- {{7 @6 |4 s: _8 Y* p5 a" L+ q5 J; ]1 A* V
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)# |. [- @! ^1 ~
    {
  E! N/ B% u: I, l        return new AddPostPayload(await repository.AddAsync(new Post& U5 T* Z8 B% I+ d2 H; g! E/ `
        {9 k3 m4 o) e* \( z' x6 d
            Title = input.Title,
/ O  e$ c" O; N            Author = input.Author' Y, H- R0 M8 g& X
        }));
# z! G# r% y% ]# ]$ t9 F% S    }
. |& a& o' e1 F6 l7 z6 ?}
/ `; d# C9 C! a. h* H3 J' F7 }$ e+ T+ r' V6 k9 w
</code></pre>
, P2 h$ J* Z1 r- D0 I! l8 H( c<p>最后在注入服务的地方进行配置:</p>
7 ^! s; Y9 F1 x% \! `0 O<ul>: s) g0 o* ~. M( s# p
<li><code>ProgramExtensions.cs</code></li>
7 f$ X  `0 R5 Q& p, T/ J: D+ ^</ul>3 P2 C8 ~& u( }
<pre><code class="language-c#">builder.Services5 A$ H- C$ \5 b6 L* J
    .AddGraphQLServer()7 z, z1 J( Z: T7 @
    .SetPagingOptions(new PagingOptions6 ^0 q+ `$ C  i2 H! P" f+ \/ E0 m
    {
: ]% r2 ?/ }3 J8 ~# O        MaxPageSize = 50,
; ^" w8 B8 s5 K: @# _        IncludeTotalCount = true' h/ a2 N0 e# X( W" Z/ g  ~+ r% S
    })
9 r, J, ^5 A5 g9 V/ r1 V6 y; F3 M: J7 d    .AddFiltering()
1 h4 b% k- T) s. q% {    .AddProjections(); _- o% g2 f% B4 S
    .AddSorting()5 ]5 Y% \7 f8 X, {% h& T
    .AddQueryType&lt;Query&gt;()) q% X- \+ s% b2 ?& G# ?
    .AddMutationType&lt;Mutation&gt;()7 h! `& x9 `$ _- F0 q7 T* [" k. Y
    .AddMutationConventions(new MutationConventionOptions
2 {$ W2 t$ v; a0 a/ `    {
( {, T$ P2 @  q3 P& T2 Z0 G: V        ApplyToAllMutations = true,
; V. z  Z9 u8 L* i* l5 ~        InputArgumentName = "input",% D: Q  m! w+ u  e5 S
        InputTypeNamePattern = "{MutationName}Input",
6 U4 D$ `: [  i7 E9 \        PayloadTypeNamePattern = "{MutationName}Payload",
+ H8 |% h3 O/ Y. u, [! K        PayloadErrorTypeNamePattern = "{MutationName}Error",$ ^/ k% A  W: j9 y; Y% ^- r
        PayloadErrorsFieldName = "errors"8 d) p$ W' N6 |. _. ~
    })* i* F, h1 Z  @
    .AddType&lt;PostType&gt;();" r8 s! @" ]3 b- s. {
</code></pre>' I: c. m* V- Z' p
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
+ F0 b$ g8 M4 T. Y2 K2 q<h2 id="验证">验证</h2>! q7 W) G- }3 _. X
<p>启动<code>Api</code>项目,调用接口:</p>( V1 x7 v  o* b; s/ ?' ^8 o
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>- g9 T7 s8 \, V/ J
<p>终端的日志输出如下:</p>
4 [$ a# ^7 {( I3 j1 O* j<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 P3 b- c3 K% D6 s8 a: D/ E
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
& C$ c, k6 r9 L; f6 q7 W, l" ]) `VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);* c9 K9 I3 z$ B6 Q9 R% }: t
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
# _6 U4 x5 I: U* }, [</code></pre>
+ S4 e$ E6 V$ Z: E) a6 q2 Q7 j2 j<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>! T) ]. L5 j- E" R1 c% Q& K
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p># T: X5 c8 `* z- v, Q
<h2 id="总结">总结</h2>" L8 W8 ^2 K! |, Q
<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>
% L0 S0 |. }3 |% d4 n! P<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
; u7 @) b) t* Q1 X, k( U" W, e. `5 G+ U- o/ H" Z' \' g
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2026-4-13 04:31 , Processed in 0.408905 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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