飞雪团队

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

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

[复制链接]

8032

主题

8120

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

7 S5 y, C+ N; k. D. Z1 H6 ^<h2 id="系列导航">系列导航</h2>; L% ]4 k8 H3 m$ @" f
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>1 O& p/ X# ]  Q" x0 n$ ^# S; m" J: R
<h2 id="需求">需求</h2>" H, w6 s3 ^  U
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
) p5 u2 X4 v- w5 w& @; C3 _<h2 id="思路">思路</h2>: S/ B) G2 J9 Z7 U. M8 L- ]" O! o
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
+ u% g  D; D5 r" a$ a  j$ w<h2 id="实现">实现</h2>% f* t- O8 r6 |5 }& T  U( X3 \8 Y
<p>为了保持简单,我们先定义以下两个类型:</p>
5 }) v9 y) _3 Y" D; K; W) |<pre><code class="language-c#">// 定义新增Post的参数9 v+ A' p! y4 `5 j5 T% r  M
public record AddPostInput(string Title, string Author);, @5 K5 G7 `5 O% v
5 ^4 W+ p3 p* v; Z. B: v
// 定义新增Post的返回对象- X. ^; |6 Q' h. A
public record AddPostPayload(Post Post);$ q+ t* e3 G+ E: ?
</code></pre>$ B# q% W4 y8 O$ g4 k
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
' |* W) p( J  l% P& B<ul>+ ?, O3 c# {  T9 ]  u  Q
<li><code>Mutation.cs</code></li>
/ L  a; I5 q4 Q- ~+ ~: X% K/ Z</ul>; p' o' Q- \8 T- C- t" i' Z; g
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
# Z5 F" E+ \" {+ v- K- l: D
# F- y/ ^2 \+ \/ V! d0 P) U' ipublic class Mutation
6 \6 ]5 |8 g. a6 X5 _+ l0 S{0 O# g, `* T& L$ R7 q2 Y. W9 L. |
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)  {8 q4 b# n8 b# @0 J* l& x" C
    {; d8 d* y3 r! I& k/ K" N
        return new AddPostPayload(await repository.AddAsync(new Post
2 x" l( Q- F$ U$ ~        {
4 u; ?5 D( ~' n0 j            Title = input.Title,
( r3 R' A& e0 k5 P% z            Author = input.Author
. A1 j; y6 w* w5 T7 R        }));6 c4 h* V: Q6 M) y; N5 i& X; ?  D
    }
- k, J; r5 U+ d}
: n7 d& F) g/ j2 D- l( g8 T6 h
9 r% f2 y$ F; ^6 v( ~: e& E; i</code></pre>
7 ^$ B. i1 S& }  f2 o; W<p>最后在注入服务的地方进行配置:</p>$ y9 w+ x. j6 B6 H6 d  }
<ul>
/ t7 M1 y+ P1 ~2 v2 M( R* p<li><code>ProgramExtensions.cs</code></li>8 }  h* j: R  L8 T, ]1 c4 U2 j
</ul>
( l9 A! Q2 H/ Y: V% h) x<pre><code class="language-c#">builder.Services
9 _* }6 {' J+ l2 R    .AddGraphQLServer()$ h# Y" ~& V% o( z" R
    .SetPagingOptions(new PagingOptions1 T5 \# N5 y6 [* o8 T# o3 C6 P7 T
    {  R! E7 n$ P3 i) N) \9 A: u9 b& B
        MaxPageSize = 50,  Q5 Q) Z$ h3 D, I
        IncludeTotalCount = true
0 `6 E% f9 `8 @# B- m; ]5 H( I) B    })3 g4 |+ M4 k9 H2 h4 g, I
    .AddFiltering()7 G4 H+ m1 B9 c$ a
    .AddProjections()! a! R4 y& l4 c% n
    .AddSorting()
2 b1 {! @1 D! C0 ~    .AddQueryType&lt;Query&gt;()9 O9 L* q7 @9 {, }& n( z7 ^- O
    .AddMutationType&lt;Mutation&gt;()
9 {# A6 O" M0 a    .AddMutationConventions(new MutationConventionOptions. |! @. ]% d3 {' X8 N$ q
    {
! A' S" j9 [0 J5 `% ~        ApplyToAllMutations = true,! q" ]: ^1 i5 k+ x
        InputArgumentName = "input"," R  J7 Q& p1 b/ g  N& e
        InputTypeNamePattern = "{MutationName}Input",
. y: r1 @1 U) _; M2 C        PayloadTypeNamePattern = "{MutationName}Payload",9 P  ^  F. W$ T# D4 Q
        PayloadErrorTypeNamePattern = "{MutationName}Error",+ v+ N% l) P/ _: L8 X- g$ u! \+ ~6 F2 r
        PayloadErrorsFieldName = "errors"
$ t. _2 s: N* X# I; J1 }; a! V# i6 n( ?    }); @8 }$ k8 E! V; Y
    .AddType&lt;PostType&gt;();4 A  a  S& y# R( z* e9 k
</code></pre>; l" v* s/ H& s! s; S+ r7 x7 P3 _; L4 i
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>- T9 G7 r* F6 s9 Q3 t. T" K1 r1 o
<h2 id="验证">验证</h2>
" N8 Q/ Q% {4 Z3 ]<p>启动<code>Api</code>项目,调用接口:</p>
* o0 ?7 q8 z4 \<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
  J7 B9 R; Y  s<p>终端的日志输出如下:</p>% w4 \/ E; ~( H( M
<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']
/ S3 p) e6 r- g+ }' EINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
' v1 {& K$ [# O& t9 H8 a: Z( b  jVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);( ?1 }8 `! g& O& X4 X: \1 l7 P
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'/ A; D% k. I4 i8 g. b2 G: _
</code></pre>5 ?6 y' W. n, C9 s& Z  ?+ ~$ e
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>7 ?- F5 N8 O3 q0 ?+ ?* s
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>, U! `- C6 C2 S+ i$ ?/ D
<h2 id="总结">总结</h2>
+ l! w' Z+ r  p, o) h<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>; y% y5 E) K5 P/ q5 i  t
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>' A% u. m0 t* P4 x

7 {# Q5 e8 v; v+ L; |
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-3 15:08 , Processed in 0.070172 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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