飞雪团队

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

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

[复制链接]

8044

主题

8132

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26462
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
6 G: Y1 _. X0 F& a
<h2 id="系列导航">系列导航</h2>  V5 |- H7 V: a7 H
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
' {* N. U0 v6 c; H) k6 T7 `8 {/ M3 @<h2 id="需求">需求</h2>
0 W: y9 K7 V$ Y% l5 X  f! n+ h<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
  d% l4 O, c$ }0 v5 z6 k: O<h2 id="思路">思路</h2>
& Q4 N5 N& v" |<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>0 F" |' c7 a% r1 {% r$ [
<h2 id="实现">实现</h2>
. B  I3 c% N1 `, v& N+ G; G2 i4 x2 U$ c<p>为了保持简单,我们先定义以下两个类型:</p>
' Z- Y( X/ {0 k( d$ v<pre><code class="language-c#">// 定义新增Post的参数
/ |: l. S; Y+ G4 g8 T5 Lpublic record AddPostInput(string Title, string Author);
' \' J/ v1 S/ c  J, a6 h
# J: G( {; B" M1 g! W// 定义新增Post的返回对象
5 Z8 q1 l; T; i' [8 ?. Jpublic record AddPostPayload(Post Post);' ]0 v0 f& j- p$ S) ^
</code></pre>1 E/ T# B6 i+ \$ C! N
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
$ x+ v. n3 G& I* v) `8 C<ul>3 @$ _8 X! R, g) C5 }
<li><code>Mutation.cs</code></li>
; R' b% X8 b) E1 }, }! G( l</ul>6 t8 k6 V( F2 N. T( l* H7 m- l
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;& N. Z: F' O, |, \2 C

6 M* g- j3 Y- a0 T& zpublic class Mutation8 z. _5 O- s9 b  {5 x* ^- T
{
& J% u7 u7 W* ~& f- L& `4 D    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
6 T$ c! H7 _. B# m6 U) u+ h- E/ d    {
$ N) D! ?0 [. g4 `7 |4 Y        return new AddPostPayload(await repository.AddAsync(new Post
% D& K) V6 g" W, N+ s6 n6 b        {& U! Q' i( b- {5 D
            Title = input.Title,
) S" v+ j: r2 j& n: [4 r, ^            Author = input.Author5 M! W5 n; z$ R! q
        }));
# O: l7 a; n+ r, E; j$ o+ u# S    }
4 D, n" n  k. j6 m2 z}
- }, z) R  r2 W! {* P& [3 P$ ]/ O7 T: c$ m
</code></pre>) ?" j" n2 q# b" Z
<p>最后在注入服务的地方进行配置:</p>
" V0 P) A9 ~7 H6 c2 N<ul>
! {/ {& C- y. ?3 h. P4 s<li><code>ProgramExtensions.cs</code></li># b4 D, u% h$ _' _
</ul>/ E) ]6 v; ^6 f6 s! {( `
<pre><code class="language-c#">builder.Services
# ~) N& m3 G, E9 _    .AddGraphQLServer()3 ~. c3 N, o) {, Z6 c( i- p' |" Y
    .SetPagingOptions(new PagingOptions6 P$ F9 p! m+ F5 N7 K
    {
, [$ b6 {- G5 T' p8 z  H        MaxPageSize = 50,
' }9 D; C" J  R" F5 L, \7 _6 k4 z        IncludeTotalCount = true) I! |7 i, d" G: o  z
    })
7 L3 o( k4 Q) R$ d    .AddFiltering()
4 y' L/ q) q, a" c* p) B7 }* Q9 r    .AddProjections()
. s5 Q5 f( W, z& J& S" K    .AddSorting()
8 ?" J5 V( O7 ]) R5 ]$ Y    .AddQueryType&lt;Query&gt;()& h) D4 q/ A- p1 E$ g9 e
    .AddMutationType&lt;Mutation&gt;()
. J* d  J4 C: G8 k4 I    .AddMutationConventions(new MutationConventionOptions+ e7 N* s+ @9 f' p
    {
! r. l% P  G9 K3 @7 M9 P6 E, d        ApplyToAllMutations = true,
. f0 o9 F& e9 i        InputArgumentName = "input",
9 x* R: h3 U: D        InputTypeNamePattern = "{MutationName}Input",1 o1 |$ N; T9 F* q0 F' c) t
        PayloadTypeNamePattern = "{MutationName}Payload",
5 y- G) o+ q$ U+ r        PayloadErrorTypeNamePattern = "{MutationName}Error",# ^; H% p% G5 j$ C* P
        PayloadErrorsFieldName = "errors"
% ~# f2 i/ i  x5 [    })
, T3 E2 |, v; r$ I. l4 B    .AddType&lt;PostType&gt;();; G* A& T' b" d. N! v
</code></pre>/ K. D. G8 k3 e. e
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
/ a  K' }7 Q( ^  z( w4 K<h2 id="验证">验证</h2>
# U4 o) q3 ]  i, Y0 d2 k' g5 C<p>启动<code>Api</code>项目,调用接口:</p>
* s. [5 E8 A& Y% v<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
" A# u$ F- l" P/ I<p>终端的日志输出如下:</p>
! e1 o! }" j4 ]7 s. t9 h<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']' D6 w/ W/ [) i2 U# h
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")% I" K4 u5 v' H1 U0 w4 {: a
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);' M. p, ?& j) g5 [. f( l, [# W
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'  B2 L+ M. L& }" f* Q0 l# f# P
</code></pre>
9 Q4 P& E% u" `<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
7 s( `( d  V- l( b$ K<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>( P& ~0 N0 y3 h& h" x" ~+ w
<h2 id="总结">总结</h2>
& \9 h5 q0 e+ P7 h8 s<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>+ |0 q! I# ?4 [) n! f2 \
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>6 `8 z0 M" t, u, k4 d
9 l6 z6 C4 s" _% q) N; z
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-10 05:38 , Processed in 0.066833 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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