飞雪团队

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

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

[复制链接]

8042

主题

8130

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26456
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
& a& ?5 k6 \2 n
<h2 id="系列导航">系列导航</h2>
7 d1 z$ ?$ s2 u  J2 S  |<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
- ?* k+ U; P% p: p) N( y<h2 id="需求">需求</h2># c9 h& y5 e6 _# Y" ?
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
6 X1 K8 ^1 M2 }! T) G. p- J<h2 id="思路">思路</h2>6 L( B! V0 b$ ]& m1 t" Z; {3 u6 z
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
. K; t2 ^1 [" M/ f0 j<h2 id="实现">实现</h2># \( W  t9 _/ q
<p>为了保持简单,我们先定义以下两个类型:</p>5 d2 V, V" {5 Y+ x2 O% j
<pre><code class="language-c#">// 定义新增Post的参数6 f2 P8 C" D; ~/ K( o5 Y9 H4 a
public record AddPostInput(string Title, string Author);  l8 J. [* Z& `3 Y% h1 a; N
. R+ g! |0 c) ~* m1 A6 U
// 定义新增Post的返回对象4 y3 l6 I( X6 \* R) c2 ]3 c. N! [
public record AddPostPayload(Post Post);
/ ~- R3 R7 x9 ^- j7 V$ M: h</code></pre>
9 \- C, ]# ?2 a) ]( }; W<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>' D5 e& {5 I3 P4 H! a& f
<ul>
$ Y  `0 v1 [. `) v<li><code>Mutation.cs</code></li>5 W* j2 O# `, f
</ul>
0 y- F0 [9 U* C+ h: n, E<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;! _/ l# U( I7 }6 X4 V# N+ y0 Q

% T/ z0 w& S) a; D1 }public class Mutation0 u0 ^0 N% x+ F( S9 w# }- V
{4 A; p: V, ]  e  H. S
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
/ u1 F9 j, W+ q' d9 j( ?    {
. e7 k0 G1 `# r        return new AddPostPayload(await repository.AddAsync(new Post
+ M6 a2 K$ ~5 q( Y        {  z( P. V4 m# t, U2 p3 w- O
            Title = input.Title,
0 I* _& m; o& f9 d' D( V* b3 N" b, j            Author = input.Author
$ _6 Z4 m  e# Z; W8 q  D        }));, p( c/ t  E! U  W5 ~
    }
9 Q" m' }! m" U. f7 ?) d}
9 l" C0 o$ V7 g  |! k2 O( ]( o4 c  H
& F& j/ H* U" H9 e' M2 H( L</code></pre>- V, x" ]0 Z8 ?3 D) k
<p>最后在注入服务的地方进行配置:</p>+ k8 g1 s$ _3 F. H
<ul>
+ u- x' z1 |4 I. z( x3 o( l<li><code>ProgramExtensions.cs</code></li>
5 x. |7 |8 V8 y1 F/ U! y</ul>3 [; E6 o- v/ \# B" O# b2 Z
<pre><code class="language-c#">builder.Services# X: p$ g0 c% e8 Y2 w) B+ e3 {; p
    .AddGraphQLServer()
! o: ]6 X  J  T( C3 B: M' I! R- G1 C    .SetPagingOptions(new PagingOptions6 }; K. I% k' }7 Z7 w* C5 Z* C
    {
, g8 T* x- D8 q2 Q/ a        MaxPageSize = 50," I$ Z( h: H( U/ Z
        IncludeTotalCount = true
* Y2 ]% B1 T- s- c" t2 W    })
! H5 E, f" ^# w2 S0 V    .AddFiltering()
* ]5 k# W" O9 q    .AddProjections()
7 g5 B9 Y2 Q. v+ N    .AddSorting()
3 L9 ]  d( C& c3 {. W    .AddQueryType&lt;Query&gt;()
' [4 N" u1 v  H! K' ^$ y    .AddMutationType&lt;Mutation&gt;()
2 w* h- _/ P6 t$ S; E( S; j2 @    .AddMutationConventions(new MutationConventionOptions+ K5 a; a8 j3 ]! d  ?( e! r- X0 A
    {, k3 C! Q9 |( G9 k, V
        ApplyToAllMutations = true,
, k" L. T% C1 a8 D. D        InputArgumentName = "input",
7 v4 Q# P' ~! b! |7 }/ Q+ y        InputTypeNamePattern = "{MutationName}Input",2 X0 E! q! L8 `2 L
        PayloadTypeNamePattern = "{MutationName}Payload",& J! n1 M  a" _
        PayloadErrorTypeNamePattern = "{MutationName}Error",
4 W9 [7 d% s' g7 Y: s6 N        PayloadErrorsFieldName = "errors"
: X9 C8 D3 ^. p    })
/ w/ O7 T2 [# D% W% B& E    .AddType&lt;PostType&gt;();
4 |& a$ s, b. P</code></pre>
3 n. I3 v  {- V& Z, y<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
9 L& f# n8 s* A6 ~. W<h2 id="验证">验证</h2>
, X7 c1 s& Y! f& |<p>启动<code>Api</code>项目,调用接口:</p>! v8 B7 t* B* T& i; D' r
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p># i& F0 ?! u4 i+ ?! {0 x; _0 f/ c3 u
<p>终端的日志输出如下:</p>( C8 z1 R" @. ~* M7 w
<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']
7 G$ q! O& d$ nINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")( \* q" h- A% k5 q, g; W( t
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
: M5 w+ q0 f5 {8 Z" }0 ][10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'3 c/ S$ P- Q8 e1 J+ G) ]
</code></pre>0 |) v3 Z& L: f6 t5 i
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p># N& f$ S" C- u& a
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
% B8 C4 J" F% t: u( K<h2 id="总结">总结</h2>
. E8 }* u1 w/ K  O- _<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>: {- T' |9 D6 S; J
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
! N  X5 e. {" B1 T% p! w% n( M; t, d6 ]4 I4 Y
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-8 13:54 , Processed in 0.061757 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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