飞雪团队

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

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

[复制链接]

7854

主题

7942

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
25892
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
% s+ ^  @$ E5 O
<h2 id="系列导航">系列导航</h2>
1 C( B! W$ x. V% X/ ^<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
+ J% v; ?1 X( r" f9 L& }) j0 j7 ?<h2 id="需求">需求</h2>
/ F. Q4 k$ r2 n% J<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>; {* T" x( w4 x7 Z9 C/ ?6 Q1 }
<h2 id="思路">思路</h2>( L0 b/ B- n, q7 z. m# K
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
7 s" D: l/ h* F- W9 T3 S<h2 id="实现">实现</h2>7 b  c  \/ [0 {6 @2 {# T4 n
<p>为了保持简单,我们先定义以下两个类型:</p>
9 u3 a' |; k* m% `1 s<pre><code class="language-c#">// 定义新增Post的参数: b2 s9 S! c- T5 y4 T+ o: e
public record AddPostInput(string Title, string Author);& A  G2 ~3 a0 b: r

0 x. p" L5 _/ L; J1 m// 定义新增Post的返回对象/ _% V6 k& o* C2 X  }
public record AddPostPayload(Post Post);4 \. V& X7 L/ D/ @9 U
</code></pre>
: M( c$ ^5 C- H/ y<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
6 E7 M; P. l" d<ul>7 e5 t+ A- P4 h6 e8 ]
<li><code>Mutation.cs</code></li>6 v2 @* |. b0 ?6 \0 ~$ ^4 c
</ul># {% E  |" Z0 P$ ^
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
" l: o$ p, T) s/ w  X6 m
6 Z* o7 {& ?6 f& K3 `# qpublic class Mutation) Z/ C. E- b7 ~  Z( @/ N
{5 l' B2 B9 `2 l
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)% E2 Y. N( f# b; f3 e" y% z. z
    {
9 A0 t$ l3 t2 ~2 _/ U7 R+ D/ h& d# K8 v        return new AddPostPayload(await repository.AddAsync(new Post
. B; r, l1 Q3 C4 h( b5 I        {6 Z$ v0 M; s. C/ A
            Title = input.Title,
- ^# N. `# l2 r) m/ H            Author = input.Author
6 n6 ?4 ~, l% g) t  E# h4 f$ k2 R% q        }));
* p4 z+ M8 `5 E7 b$ s3 n: }    }
0 B7 O8 N% d2 H6 p# b" U}5 Q4 S1 N2 L& c% I/ {

9 A% I1 W( J. ]</code></pre>8 {; c, P0 X! ?
<p>最后在注入服务的地方进行配置:</p>
% X7 t% t9 \! W+ U  z<ul>9 \$ y  O, K6 K' S5 n/ N
<li><code>ProgramExtensions.cs</code></li>2 i4 ]5 O; q; q! H2 P
</ul>
# Q1 a7 j/ B2 m6 d# d1 z; Q0 O% v' B# [<pre><code class="language-c#">builder.Services
! E# y* d- s! H0 v- X    .AddGraphQLServer()
. Y% g9 {+ l6 @; {) ~5 N    .SetPagingOptions(new PagingOptions/ T& o" I. V2 R/ s4 t' U9 A
    {
' \- C# v& @$ |$ a8 k9 i- W5 F        MaxPageSize = 50,
' N0 P" I) d- g7 V% X- E& q" O        IncludeTotalCount = true! x- Q9 Z& o9 u" d- P0 I2 ~
    })
. o$ }1 s: q9 l9 Z* c# @  t4 M    .AddFiltering()
/ @  k- @! n2 b, {$ U    .AddProjections()5 ?0 Z# K" S5 q* J
    .AddSorting()
- C- T* R3 ?- |# |    .AddQueryType&lt;Query&gt;()
' m- ?$ ]* i, O" Z    .AddMutationType&lt;Mutation&gt;()$ p$ b7 {' W0 q9 s, o2 H# w& w) Y
    .AddMutationConventions(new MutationConventionOptions
- `, |2 f/ M% M$ R! V: U  t    {/ g, `, H5 F  P
        ApplyToAllMutations = true,
6 }5 \; h9 |. A7 i        InputArgumentName = "input",6 G/ ^6 ]* k5 n" }' k
        InputTypeNamePattern = "{MutationName}Input",9 y" \& g5 L8 {7 S3 Q3 u
        PayloadTypeNamePattern = "{MutationName}Payload",& c" I4 j" k. a9 Q. j% i- m
        PayloadErrorTypeNamePattern = "{MutationName}Error",% d# @! G+ x! b  z; H$ {- u
        PayloadErrorsFieldName = "errors"$ p5 F& S7 X, Q/ {/ [
    })
. a1 A. w8 A) \    .AddType&lt;PostType&gt;();" o  c4 o/ N/ G, y
</code></pre>3 c' ?( L2 ^. j- r, i( u7 U$ o
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
! R! k3 O' {; `1 c1 e/ W% l+ m<h2 id="验证">验证</h2>
1 |* s4 o# z0 L" a0 r1 |<p>启动<code>Api</code>项目,调用接口:</p>
, U! ?6 r: v: t2 R0 {<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>& |2 h0 Y4 ]  z3 c+ |
<p>终端的日志输出如下:</p>
/ _" Z  L( a4 d5 y" O  ~9 j<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']( g6 w' {. I- b% w% `
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")% L6 c  J! [1 Q  [8 v2 z5 a6 p
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
, b; `/ P$ s5 z) ][10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'( G' v4 s8 ^3 {: q) K  ?0 ?+ X
</code></pre># r5 e3 H0 r7 C: ]1 R
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>2 I: M6 a+ g) u) }  k
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
) M& Y1 U# q' {1 {/ M, F7 ]<h2 id="总结">总结</h2>/ b" m0 |; l# n) W1 u% H6 q: N- r) A
<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>
5 j% p  K$ W9 b, R, A1 k<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
/ f! T7 {) r- a! [( H5 ^! M( v, d, ^& H4 G- H; Y9 Y3 `5 F& a
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-14 03:16 , Processed in 0.064338 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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