飞雪团队

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

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

[复制链接]

6870

主题

6958

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

" S' G9 h( k: W+ O5 |8 L<h2 id="系列导航">系列导航</h2>& ~# M& L2 A4 h0 P1 f/ G8 Q6 X0 x
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>5 T( L, u5 W9 a% ?5 Q
<h2 id="需求">需求</h2>
$ K! n1 I8 U( g  j1 [<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>/ Q: s) m* b0 G7 B
<h2 id="思路">思路</h2>
. P* x* F3 I) f$ ]! w<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>- u8 y" U' D5 G8 I
<h2 id="实现">实现</h2>
* N' Y% Q0 m& |% `) b9 m<p>为了保持简单,我们先定义以下两个类型:</p>
; {7 M) H* f  D$ X- N! Z1 X5 \<pre><code class="language-c#">// 定义新增Post的参数7 Y9 t3 Q& t. G
public record AddPostInput(string Title, string Author);+ W7 R( m: c' ^  D! D
: b8 r* y. w- N6 @3 U+ i3 p
// 定义新增Post的返回对象0 b" J% C% @6 L4 c3 B
public record AddPostPayload(Post Post);
2 T6 z1 k; `% L2 g" d</code></pre>5 d5 ]3 L1 c* u8 A) g0 C
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>( H7 C( V' Y, y% i9 r+ C" r0 }2 m
<ul>
! X# C2 o  Y) p8 \<li><code>Mutation.cs</code></li>
" I0 \4 ^) h8 D; i6 b9 J6 i7 }4 m</ul>
; b/ S' ^8 ~. N4 P<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;( p5 ]6 t: V! y
8 s! \, u- R' J' q$ `+ c
public class Mutation3 I4 ^& n/ Q& {
{
9 _1 ^+ T+ t' U6 E# [2 i    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository); c7 [# j* Z6 e, p* `
    {& U, k& M: N: p/ Y+ d, s. V/ }
        return new AddPostPayload(await repository.AddAsync(new Post. h  i( ^' A8 w- W" s+ k& x
        {
4 ?6 n. ?' X/ g& o6 Z4 E            Title = input.Title,9 P( d. }# C2 M9 s
            Author = input.Author  I. s: S/ F; c  a. A; r# l! I
        }));/ s6 S" o$ q* w$ ]) m, J
    }( Y6 G, P5 G+ L7 V9 Z3 v" {2 R
}
, u% @+ P9 w  ~3 F  ^2 t. Z" |; [: q& o! k
</code></pre>
" }5 m$ o9 U& J& Y  y( j6 ?8 K<p>最后在注入服务的地方进行配置:</p>1 c, U. L8 X/ g7 z& P* P8 q
<ul>; c: }- F: m/ D+ _! Y+ U! h" L
<li><code>ProgramExtensions.cs</code></li>
7 Y* j( W; S, I9 D, f0 J* R</ul>
, B( {: V6 N; L. `/ m7 Q! o<pre><code class="language-c#">builder.Services& _) v* W, u( ~
    .AddGraphQLServer()+ T  B) {6 V7 W( v( E' O
    .SetPagingOptions(new PagingOptions* C4 f4 E% O: }( I
    {
" o1 S6 w% N5 a        MaxPageSize = 50,7 j8 K6 A% t4 |
        IncludeTotalCount = true6 E4 J1 v: i7 t0 U4 s
    }): w7 C' v4 D' d
    .AddFiltering()( ?0 s# }: H5 `) e" r
    .AddProjections()
5 ?1 I* j0 b* C( o; z/ o1 s5 K    .AddSorting()
. S% \# O, w- `0 @/ \. l5 H    .AddQueryType&lt;Query&gt;()0 Z, J4 A' g% @
    .AddMutationType&lt;Mutation&gt;()' X6 G2 H2 O8 q" R- Y2 v) B% P! V
    .AddMutationConventions(new MutationConventionOptions# q. G- ^1 W4 c
    {
  |, Q. K2 V! k8 B( a. x        ApplyToAllMutations = true,
3 R) i3 @/ f9 x        InputArgumentName = "input",! A9 k- ~- K+ d
        InputTypeNamePattern = "{MutationName}Input",* t3 p. P* m! Y* s8 y
        PayloadTypeNamePattern = "{MutationName}Payload",
  ~: }8 @- R+ Z- [) m, ~        PayloadErrorTypeNamePattern = "{MutationName}Error",2 B! y* }% }9 R1 l
        PayloadErrorsFieldName = "errors"8 F& m0 [) ?+ E' j& B0 B
    })
, h3 F9 f6 k8 s! `, m: m* b    .AddType&lt;PostType&gt;();
+ V+ f/ l0 Q! n' s</code></pre>
& k, R" M5 S/ |- b<p>这样就实现了新增Post的需求,下面我们来验证一下。</p># |& ]' U( |0 e. B! B# m% H& l  V
<h2 id="验证">验证</h2>
% g! q: H+ X  h9 l+ e3 x<p>启动<code>Api</code>项目,调用接口:</p>1 ]' M0 A4 A4 _
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
% m  M; ^6 F/ q3 w; f4 k0 d9 n# P<p>终端的日志输出如下:</p>2 y" K+ k* }4 W& t
<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']
; g$ [6 m' w5 DINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
: Z. ~" w  l# J% r) t5 h' [VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);/ E; k+ C2 Y. G
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
! c: V9 _/ ^% S1 ]; b</code></pre>0 w5 A2 X- A7 x* |# Z
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
- b; w: K7 R# Q+ p8 i9 v<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>; ^: h) Q) u1 d& m7 e+ V
<h2 id="总结">总结</h2>
9 H) x& P/ A" N: K' G  I/ r<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>
/ q! P  N/ e) f8 N) e* f+ [<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>  _. U8 [( l4 S: W

1 i, M2 j  M3 Z7 r
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-7-7 11:04 , Processed in 0.061168 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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