飞雪团队

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

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

[复制链接]

8019

主题

8107

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

* i8 |4 n+ N9 _6 {, H$ J: f: M<h2 id="系列导航">系列导航</h2>
/ W6 Z9 m  B! K5 _<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>+ U/ C8 w$ ^' I8 }% U- p( y2 k
<h2 id="需求">需求</h2>
: j' F  O0 E; r4 f# d<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>& {% n: P: n4 X& i
<h2 id="思路">思路</h2>! y1 o! ^$ O9 g& R% d8 E9 A, o
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>9 J( w8 L! A1 Y3 u) d7 u
<h2 id="实现">实现</h2>
# F9 S1 {/ k' M* t8 s! ]<p>为了保持简单,我们先定义以下两个类型:</p>0 ~( \2 J" O! G" ~* L
<pre><code class="language-c#">// 定义新增Post的参数
5 Q, y, B( I0 d7 Tpublic record AddPostInput(string Title, string Author);( j8 S! f. n; L; N! f0 t2 z
& O' C! A/ V; O5 _  f, v
// 定义新增Post的返回对象
2 S: g7 R/ [7 t0 X4 W' X3 H# Gpublic record AddPostPayload(Post Post);  ?" a4 h- {) u( ~; X7 z: B
</code></pre>3 k  W: P* n6 @# Y" J% o. i
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>  O) X- v2 _; e" }6 @$ F2 Q
<ul>
7 A' n$ R5 k7 {0 ^<li><code>Mutation.cs</code></li>
& h% d7 p" |0 L# I, M0 I+ {</ul>
. o. d% F; _8 a0 W: v  w<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;" X9 K+ L" r/ c# ?. B8 \" G

8 M; U; v; a7 m" e* lpublic class Mutation2 [" S! k! J. a/ \* s
{
% w: N1 p. o, V5 Q8 ], A    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
% K8 e. Y) g, b2 l1 P5 `! R9 q    {- ?# f# i. ]0 K
        return new AddPostPayload(await repository.AddAsync(new Post) m& k' h, H' G1 ]) B
        {
7 ~  I. w: C+ W+ N7 W0 B# l            Title = input.Title,, I5 n  @/ S: Y9 d7 q. d
            Author = input.Author
; x8 N5 N$ K: `3 X, y1 Q1 ~+ d        }));
* D0 U/ A! K7 {/ e8 V    }
. m& d" J5 H" C, r% ]5 P}
/ @) H0 ?$ \( p8 y
$ I- ?0 g, {2 [8 t% O4 U</code></pre>
; @; Q' u! H! a6 y) i<p>最后在注入服务的地方进行配置:</p>0 x- q# x3 y* b4 O/ T( v) U
<ul>( C! l# y8 z: I. B" I9 J
<li><code>ProgramExtensions.cs</code></li>
. k3 w+ w* T1 X</ul>
% J, L  `" S4 _<pre><code class="language-c#">builder.Services
# ?6 q4 O& ^% F6 [1 j    .AddGraphQLServer()7 g* K- Z- Z. N
    .SetPagingOptions(new PagingOptions
  c9 `3 D$ T+ J- z; j  c8 C; d    {! B. Q0 @) t* a( `1 U' x7 J, e
        MaxPageSize = 50,! J' n$ l/ x# I4 ~5 H& I8 [/ @
        IncludeTotalCount = true
$ u7 n5 [' a! O1 l    })  `/ j" S0 Q6 d6 U) D+ ~' P
    .AddFiltering()
4 g& X; F8 `. {    .AddProjections()
4 T# M2 Y, y' v  [* y+ I4 w8 u* t    .AddSorting()" M8 F7 s6 @7 ], n& O
    .AddQueryType&lt;Query&gt;()5 H6 D$ [$ a! B4 v& r) J5 o( H
    .AddMutationType&lt;Mutation&gt;()& o/ E# O; a# _/ _
    .AddMutationConventions(new MutationConventionOptions. ?; ~* {0 J( J0 d( c5 Y" r: [
    {
& g" ]# ~" O9 P6 V        ApplyToAllMutations = true,* Y" Z- a+ c" j* F. I! @2 G+ l
        InputArgumentName = "input",- y  d) U/ E$ S" C  c; `7 @' n
        InputTypeNamePattern = "{MutationName}Input",6 _+ A- }. \6 @
        PayloadTypeNamePattern = "{MutationName}Payload",7 M* B2 m1 k* d' v* A
        PayloadErrorTypeNamePattern = "{MutationName}Error",
2 E; X+ i6 U: j+ c  m, O) V        PayloadErrorsFieldName = "errors"
  w, |% [+ C7 L$ r4 @/ s    })
1 B$ i* A- A0 I% H& K& A" z    .AddType&lt;PostType&gt;();
/ m! Z2 v- R/ `! T/ ]  C6 ?6 I( o</code></pre>
, R5 |$ Z& n/ l# b! ^* d. O<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
  v: z5 w  K' l) K5 j) i<h2 id="验证">验证</h2>
/ s& `0 W* X1 A9 h9 u<p>启动<code>Api</code>项目,调用接口:</p>4 I2 k% H0 [8 @1 }  p
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>) o' |* B2 g4 ~$ C9 o% g" |
<p>终端的日志输出如下:</p>7 q3 O; B( X# I
<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']- }, o; |' u9 O5 O. _9 X- g7 z; l
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
+ ]+ Y& U3 |+ O  m  S& tVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);& S3 i9 u0 y0 K6 \; W9 z* r' Q
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
( v- A+ B! v  w& q- N' l</code></pre>* p& O/ }3 f9 B9 c' r/ O
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
8 e) t+ ~- P. z<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>1 o8 p; c* p' o3 \  b
<h2 id="总结">总结</h2>
$ x! l$ a9 R6 e7 |% I! k' l2 T<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>
" P) L4 a% c: c  Y  J1 j<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
( k  Q7 `' e" v4 h4 x& r2 ^* s5 d( K% t, y
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-2 06:22 , Processed in 0.059125 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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