飞雪团队

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

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

[复制链接]

8059

主题

8147

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

8 q( L8 A0 g* L. u/ F8 Z<h2 id="系列导航">系列导航</h2>
. \# p$ j# |6 w' k. \- l<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>8 {0 Q6 \- o7 O
<h2 id="需求">需求</h2>
5 i2 P3 B7 j! [/ x<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>. L& _) N% b0 l# x/ T6 \* J- L
<h2 id="思路">思路</h2># C3 E6 V' |$ g
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>* m& i1 P# e3 c/ ~
<h2 id="实现">实现</h2>
3 G2 w1 Y8 g0 k( C2 C<p>为了保持简单,我们先定义以下两个类型:</p>
& G8 V$ e+ d  _6 V) a<pre><code class="language-c#">// 定义新增Post的参数# R" d1 i. Q: }% N1 w/ q; U
public record AddPostInput(string Title, string Author);0 t2 S' F5 J6 k4 p& P

1 b! i- m5 p& |7 u# I' R// 定义新增Post的返回对象/ N. \- O0 \4 R- l# k1 h
public record AddPostPayload(Post Post);
  l1 C! }' [" o. W) \</code></pre>
. [" l& ?  M1 B<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>7 g( n2 j1 e! K. a' h
<ul>6 R  h0 j2 Z+ U9 }
<li><code>Mutation.cs</code></li>5 n4 _1 B7 M8 ~! V2 {0 `
</ul>
2 Z0 S9 y8 k, }# M<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
/ r" I2 A# g/ f0 u
8 E, F! @: _5 @  B, E2 gpublic class Mutation
: J" A7 ^. _$ H2 I1 N' u{
# Y; V0 ~5 b8 c( B+ d    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
* X, L" Y; a. \    {1 |2 P* e' W) |0 t- r# ]/ g6 \
        return new AddPostPayload(await repository.AddAsync(new Post
' ^. A6 n- i$ L3 c( i        {0 z( F: J3 p; s% b6 p- O
            Title = input.Title,
: D1 i& _% X; b6 a* K            Author = input.Author+ I; q3 Z" {$ |. [+ e
        }));3 B2 z/ Z* \7 {/ i1 T
    }
0 S1 ?( P- E) y# N6 @2 n# e}! O5 n" }$ [+ H
) U9 p: x9 f& }0 D8 m7 p9 N
</code></pre>+ e% j0 q/ j# ~" g% B$ Z
<p>最后在注入服务的地方进行配置:</p>1 h2 t& c6 p6 j3 l5 L1 Q
<ul># {. {! Y4 z7 @7 ~- F& F
<li><code>ProgramExtensions.cs</code></li>2 Q) s' F0 c1 r9 x4 @/ {
</ul>, O4 @6 A3 k" w3 ]. U3 h
<pre><code class="language-c#">builder.Services
( X) f, l) I5 K8 ~& v    .AddGraphQLServer()
7 c% {( u% {) c9 o- J    .SetPagingOptions(new PagingOptions
/ C: I* L  J& l/ U" e0 n) \# ]% Y    {
9 N* `7 o' M( h' K        MaxPageSize = 50,
. s+ V' B% z/ R( L4 m% C        IncludeTotalCount = true
8 b% T( {! U6 ^# N4 \    })
& L& F2 A' r: Z$ W/ s" U7 C    .AddFiltering()
7 }7 z1 l2 e" ^5 `% L; q    .AddProjections()
3 r. X: n! h0 R4 U, S" n6 X% z    .AddSorting()7 K# M, L1 G' q. _7 n( o3 |
    .AddQueryType&lt;Query&gt;()+ [3 R5 m/ Y8 Z, Z" X
    .AddMutationType&lt;Mutation&gt;()
3 w* A) }0 f6 c: C: u8 G    .AddMutationConventions(new MutationConventionOptions  H- Y& m" }- q+ O
    {+ f3 i* {( G& M, _
        ApplyToAllMutations = true,
8 T6 E" P! I" Q6 N2 T0 T, S        InputArgumentName = "input"," K! E# q+ m$ Q, g# W+ s" C
        InputTypeNamePattern = "{MutationName}Input",
5 ~  `$ E8 F% ~+ [6 H        PayloadTypeNamePattern = "{MutationName}Payload",/ ~+ `2 Q/ c* x* x
        PayloadErrorTypeNamePattern = "{MutationName}Error",! b+ X8 m+ G6 y* j; a5 h2 X7 y, ^! L
        PayloadErrorsFieldName = "errors"6 e( x2 Q# N" H
    })1 ^0 m4 s) u/ X) B  \+ v
    .AddType&lt;PostType&gt;();
' w5 U' J  z" Q1 ~0 f4 M, v* q</code></pre>
5 _3 {( I; K# e+ L* q: ~<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
& f6 D6 [2 z; J<h2 id="验证">验证</h2>% `; G- a, U' b' T  K/ I; Y1 z
<p>启动<code>Api</code>项目,调用接口:</p>; C; G$ |* }- v3 y) `* g
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
: R* |& t# E6 f" X% b" N<p>终端的日志输出如下:</p>, I: A/ E' S# B2 r3 x7 D1 e2 z( T
<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']. p0 I5 r" H6 b; Y7 M+ V; W
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")  p4 x  c8 Z6 ~6 Q# K
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
# N4 W3 S; f+ v: _: R2 P! F4 x[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'- t- L) p. [' F6 _
</code></pre>; t8 L( M5 f6 M+ V: K
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
$ l3 Z+ V+ f5 N) T* X<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
8 n- y/ w+ f/ N1 M) b% P- o<h2 id="总结">总结</h2>: z/ v# W; l0 T: j: b8 }
<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>
, ^& W9 ~& r/ h% u* _: M1 o& t2 @<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
& T9 ]% \6 g6 \( r: s2 I. L( f" T% o7 T: R: w' j8 Q
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-14 21:23 , Processed in 0.066066 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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