飞雪团队

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

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

[复制链接]

8040

主题

8128

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26450
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
# ]& F* p. S3 n5 B! j' n& G
<h2 id="系列导航">系列导航</h2>
: B: D: \  V* X2 B5 c<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>; P' {  y7 l+ i
<h2 id="需求">需求</h2>
# g0 _3 m( R/ `, `<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
' [$ t& K0 d8 L! L<h2 id="思路">思路</h2>$ d; p# a: G$ H( ~0 Q6 z# c" [
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>( g( m2 q: q- [1 R# C9 @5 u
<h2 id="实现">实现</h2>3 D! k! F! W3 W8 X7 p4 {: ]( U
<p>为了保持简单,我们先定义以下两个类型:</p>
6 [* J, Q* ]$ U; N# K4 E9 E0 h<pre><code class="language-c#">// 定义新增Post的参数, w5 q; z7 }/ u9 f) p
public record AddPostInput(string Title, string Author);
  e( h1 M( c9 y; r9 w9 n9 G1 `. ~5 Z7 I; t. B" D% M1 Y$ Z" @
// 定义新增Post的返回对象+ _; |+ Q' `+ o6 J6 ~( @" T
public record AddPostPayload(Post Post);
# X& p' Q' D) ?4 I& I/ m  S</code></pre>
- F: R8 m, f( ~( `7 L# P& K* j<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>. r: Z5 n8 u, i2 N
<ul>  _+ [, f7 U- V$ j9 Q. h
<li><code>Mutation.cs</code></li>0 a8 v. n5 y( {' W3 D
</ul>+ i8 p$ g8 @# t2 o) R& o
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
" S- e6 r8 _( _$ k) L$ [+ Z4 _' ^" [$ K& b8 L* k4 A$ _! i0 L
public class Mutation
# N  O8 V  ]1 a3 s+ s- h" v{
& c6 e: O5 F, Z' i& f) U' {    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)1 h7 q) {' ?% K2 K% q0 g
    {
1 l3 b5 G6 D) b" L! G        return new AddPostPayload(await repository.AddAsync(new Post
) F; h, P) V9 p+ L4 N% x8 \2 [        {
* X. V+ V! B+ B1 v8 H& z            Title = input.Title,  \% i. ~1 @2 W/ @. I- e
            Author = input.Author: m0 y5 x  W% n; c9 J, m8 L" X5 n9 L
        }));
8 \* j  i0 E# e( r& w7 t8 `    }1 @; A7 {' }3 F  Y4 D/ @
}
0 E7 R( J# A3 b6 R" u
7 {9 Q5 c' [0 a! h</code></pre>
# h! ~) e* b8 ^7 |" }. C<p>最后在注入服务的地方进行配置:</p>
8 [0 n7 @. l$ H7 ~9 k<ul>! V8 p: j2 S2 i- M
<li><code>ProgramExtensions.cs</code></li>9 b! M! ~7 K* ?0 r! |- R+ t
</ul>
) J' P! T9 D& u  m<pre><code class="language-c#">builder.Services* U0 m- L: f- V4 E( U+ |8 ?
    .AddGraphQLServer(), h/ \' I( O) v! i' k9 B1 F
    .SetPagingOptions(new PagingOptions
: u3 ^" c" Y# r) S9 \    {* W% M* b- Q& m) k; W2 u! s
        MaxPageSize = 50,
4 L) N/ |, [0 p! c' I' C; B# h        IncludeTotalCount = true
- ^3 q/ U! R0 O, @    })& j- d; x: T8 g
    .AddFiltering()! ?6 m) N+ I% D( ]3 K5 M9 o
    .AddProjections()7 z5 B, J- J# z7 p5 |2 s  K
    .AddSorting()
5 e* e& U7 t0 ]0 g9 B! [1 J. E' s    .AddQueryType&lt;Query&gt;()6 I3 v; J; W: k  N
    .AddMutationType&lt;Mutation&gt;()% a$ H+ G6 \- U
    .AddMutationConventions(new MutationConventionOptions+ h' b$ f$ q! q2 Q1 D, Z
    {7 ~% b- H9 k+ I
        ApplyToAllMutations = true,) M" K' L: b8 ~- z) e+ }
        InputArgumentName = "input",
7 F7 d7 Y. s) C, T' ]        InputTypeNamePattern = "{MutationName}Input",4 m8 D1 }$ D6 B: l. B: `7 e8 u
        PayloadTypeNamePattern = "{MutationName}Payload",
0 B7 m) M' \# D, W! J. D0 `        PayloadErrorTypeNamePattern = "{MutationName}Error",/ c- u) y% h$ ?. n
        PayloadErrorsFieldName = "errors": v0 r- `& `* q# t
    })0 k  S- q, V+ v7 w: T  I0 X' N+ |
    .AddType&lt;PostType&gt;();: y- G4 k8 i3 e9 ^5 O6 F4 T# r3 \
</code></pre>! s5 N' x! t- W8 Z+ n7 k4 W7 K" d
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>; P4 L, m) E% q3 m
<h2 id="验证">验证</h2>; L+ F  r  Y( N+ j
<p>启动<code>Api</code>项目,调用接口:</p>
: d; b$ d7 p! u<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
1 |9 }$ W2 U4 E5 u<p>终端的日志输出如下:</p>& X+ ]; D( t2 o
<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']
. r5 f' \: |3 Z  f. B% n) DINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")/ p  g7 b; Z. h; H& A2 Y4 Y
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
0 l% T+ p- G& I5 G' m8 H( @[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline', e( _/ P& s* T/ r' n/ F- {
</code></pre>0 D7 u7 k* C0 [+ J* m: i7 Z
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>) P) O1 p7 ^) u! M
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>. O# X& r* b9 f0 ?3 X2 q2 m9 w
<h2 id="总结">总结</h2>
6 L+ ]- C  |7 j/ g# Q3 S* y<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>
. B8 o. ~: k- e2 M  o<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>* |, h9 Z. ^1 E* \6 x. g
( Q& [: \0 A6 L  |" n1 ^( M6 e  a5 X
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-6 20:53 , Processed in 0.144720 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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