飞雪团队

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

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

[复制链接]

7928

主题

8016

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

9 m1 j: C5 {  B/ _. n3 d<h2 id="系列导航">系列导航</h2>
) ]$ N3 I( ]- P+ l4 o# P9 m- a<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>3 T/ k3 z/ b8 m  g/ J8 Y1 p, t  M
<h2 id="需求">需求</h2>1 e2 i1 D# J+ T$ O( `. K. M
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
6 B: L$ w( b# x$ Y<h2 id="思路">思路</h2>9 O. @7 }& _5 W' ^; Q
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>. P" V( M6 y. D# ~1 b
<h2 id="实现">实现</h2>7 K; w" X( i9 J, E# ~( i
<p>为了保持简单,我们先定义以下两个类型:</p>
/ l3 w$ E; q0 X* M<pre><code class="language-c#">// 定义新增Post的参数6 I2 S' c' X2 l! P( {' p1 j
public record AddPostInput(string Title, string Author);2 Q. b, w' ]; a- M3 w/ i

! `* ^& F9 \# Y9 n// 定义新增Post的返回对象
8 l" f7 r2 o, \2 \public record AddPostPayload(Post Post);, }: d7 ~2 D( r/ T# o% R- N( m$ L
</code></pre>; {/ R* L( W1 h3 ^
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>1 M- q9 d# `, e8 L& g: J/ h" l
<ul>
( I3 Y, _& n% N) J<li><code>Mutation.cs</code></li>* j2 m8 b" l  d
</ul>
0 A+ [  ^# R, g/ k2 L<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
9 k1 B8 W3 ~! A7 \+ a% M/ E* z! U6 C! l
public class Mutation$ Z% Q, O& @- D% S' w
{  o& l7 \5 q1 y0 c' ?$ q
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
: I$ }' N; E( m. H5 Z3 V    {' ^4 u4 y5 E( G
        return new AddPostPayload(await repository.AddAsync(new Post& v- U# x3 \$ N7 w, A; S0 d0 z' Y2 `. k
        {9 L/ Y  _% J" ^9 P6 I; A
            Title = input.Title,+ p$ \8 r4 s! x3 R* e& L/ |
            Author = input.Author
  {) w  g7 `* G4 n7 [        }));0 x5 j, _3 K% e# ~1 o$ ~% ^! W5 v
    }% @5 U0 c/ Y1 c2 B4 S" _
}: C& B# L2 q0 N/ I3 u: S+ S8 `

+ a! k; S. @* {! D- Q$ r</code></pre>
& }  y& i' r" K5 ^! y<p>最后在注入服务的地方进行配置:</p>! B- t& m# V/ {5 Z
<ul>
. U1 ^/ J  V2 q& v. ?9 R, u<li><code>ProgramExtensions.cs</code></li>8 E6 C% w0 A# G* n
</ul>" ~) D7 r- G1 }
<pre><code class="language-c#">builder.Services# z/ r$ c: b9 h1 v% w0 x6 J
    .AddGraphQLServer()1 |; K2 ^! M2 F4 ^. L5 q/ v
    .SetPagingOptions(new PagingOptions$ ]) V! h$ E  n$ \
    {# P# o5 y5 |  v. X. R: o/ l
        MaxPageSize = 50,
! B- P& c/ q% Z( e( [9 _/ G& h        IncludeTotalCount = true- x3 Q; C1 a# q  z/ X$ y
    })+ B: F* z5 ^1 h1 {, V3 Y0 ~
    .AddFiltering()3 v" @% [2 V' t* Z4 g
    .AddProjections()
$ }8 y& s7 Y9 g: {% ~    .AddSorting()
( W6 ?7 i# v! e3 w9 F" _    .AddQueryType&lt;Query&gt;()$ T' C( t: s5 @$ g4 ~6 I% o
    .AddMutationType&lt;Mutation&gt;()/ t4 C3 j8 }, V: x
    .AddMutationConventions(new MutationConventionOptions
3 h7 u3 A3 Q- V    {
+ Z/ Z; P7 f9 P2 Y9 M  V, c. Q        ApplyToAllMutations = true,- y: n5 u2 `+ U: Q) p: c
        InputArgumentName = "input",
1 o0 q/ l$ N* `. w! F' ~        InputTypeNamePattern = "{MutationName}Input",; ?$ b4 J9 w) {" S2 x: E5 o- ^
        PayloadTypeNamePattern = "{MutationName}Payload",
1 ~3 ]) N9 [; N$ ]1 J6 Q        PayloadErrorTypeNamePattern = "{MutationName}Error",
' G3 k0 g/ I# w3 Y  F6 e& R        PayloadErrorsFieldName = "errors"
9 |' Z8 f% f6 i. j$ E3 f( j    })
& v9 e- C- N  F5 V9 i4 B2 d' w" _    .AddType&lt;PostType&gt;();& d+ K7 C; F$ U4 m
</code></pre>+ r% d5 s4 ?3 _
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
2 i& P2 W" B& \7 C* s% P# ]<h2 id="验证">验证</h2>; A% W9 Y/ v8 p4 ]! ?
<p>启动<code>Api</code>项目,调用接口:</p>
: W0 n9 E. d1 G- f% b% h<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
3 n8 J: q" a7 C7 o  |<p>终端的日志输出如下:</p>
' V5 r7 y% u/ n& x, f$ R3 _  O: i$ G<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 |! r# l- b$ F% k2 [INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")! [/ e3 Y0 G" M
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
; o$ ]7 N% x) g0 c( T/ b2 `[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'* r6 Y- _2 G9 M' d9 G8 z8 {. e
</code></pre>3 i9 y4 R2 h: T0 z: _5 }$ X2 A
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>! i* ?& U$ E7 }4 }6 M
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>: L8 _* N7 o  A6 w/ I- ?& [; O" i
<h2 id="总结">总结</h2>3 M, ~5 y+ E% u+ O9 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>+ X  K' L, \/ n. P& H- ]0 x  m
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>. n% u' Q9 P8 C5 B: S

: J7 ]: A1 b2 o5 w
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-22 19:29 , Processed in 0.062645 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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