飞雪团队

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

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

[复制链接]

7953

主题

8041

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26189
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
6 C6 [# F2 w( G6 g/ ~1 |5 i
<h2 id="系列导航">系列导航</h2>! L3 P6 Y, N' z7 j4 v7 `
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
5 f8 J5 F$ {; u% w<h2 id="需求">需求</h2>: C( n: T: d* E% S; J9 }1 e
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
, @, l- Q, ?% G; {& ~: O7 A* J<h2 id="思路">思路</h2>5 M  [9 S6 t9 A2 A8 X( x' W4 G/ G2 h) G
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
  o. Z" ^+ a& e, _8 }0 C- r, W<h2 id="实现">实现</h2>
: V/ x5 |; P$ a: }) \( W- Y5 y" x<p>为了保持简单,我们先定义以下两个类型:</p>- V! ]- k" K( w& A
<pre><code class="language-c#">// 定义新增Post的参数6 K* v) f" ^: i5 e. o, v6 U
public record AddPostInput(string Title, string Author);
$ U/ Z' W$ x6 |9 e8 O. {" o
" s) u5 ~' D0 A* G0 Q// 定义新增Post的返回对象
7 y5 G6 M8 h5 T2 T4 p. opublic record AddPostPayload(Post Post);* }: N5 i. e% X8 F0 A5 O  t
</code></pre>
  X- E9 Y" S) o<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>0 R; l9 ]) @0 D% R
<ul>
" _/ X/ v  E/ T# q: U9 s* {: y( J" @<li><code>Mutation.cs</code></li>
9 x  @( M1 J6 _+ o' D</ul>
( w! r  K$ N0 o<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
% N( ^& I9 j) J1 _" `5 X* X
1 v1 `/ y+ S7 h  }public class Mutation/ X8 a' a& ~5 Q7 l1 s/ Y4 M, f# @
{
, B1 c- E2 Z3 i7 L    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
; L4 l# N0 y" n" ^( M& c6 |4 P    {& e$ ]$ J! q0 Q$ E4 s
        return new AddPostPayload(await repository.AddAsync(new Post2 ]/ ]& Z5 Z# ^
        {3 h- l9 j+ D, Z" x& a6 a
            Title = input.Title,+ Y- e6 j8 r  U2 W( u0 }6 g
            Author = input.Author
+ N* v- Y" w+ }        }));
7 P+ X* Z% l* b( F6 L+ V) T    }
! g; |0 a8 [2 U}; t. C: B! b( w

9 E6 q( s# S9 u</code></pre>
' D7 q$ K! K- P3 K+ `1 p<p>最后在注入服务的地方进行配置:</p>: y, p8 a, F! q3 ?% {. T+ a. f% W  P8 }
<ul>( o; ]1 _& Y" r7 R0 W
<li><code>ProgramExtensions.cs</code></li>
9 D9 a& c9 q  x. n</ul>/ j  d, u$ O4 z% K7 t$ b8 i
<pre><code class="language-c#">builder.Services
* t. j' G9 |3 T+ u9 A& e    .AddGraphQLServer()" P  ?4 R1 k: q7 q, f
    .SetPagingOptions(new PagingOptions
0 n2 E. L4 W# F' z; \' P    {
- s2 \) G9 \2 [, O        MaxPageSize = 50,
, s* T5 W4 t* t/ l        IncludeTotalCount = true. g3 F% Z, _  X& q' M2 ?
    })
2 o# I+ H( f2 j7 N7 o0 B    .AddFiltering()
" a7 r% k: _( Z) e& @% d2 r    .AddProjections()
# J; h& x3 b' Y4 Q    .AddSorting()
* y# u. d; k- F9 D    .AddQueryType&lt;Query&gt;()
. e# j* z  N8 n: X5 l    .AddMutationType&lt;Mutation&gt;()' L  l2 j, ~* G9 ?3 k
    .AddMutationConventions(new MutationConventionOptions
$ K9 R% d. x$ f: h4 I    {. V/ O. L9 M& q- Z8 e  {
        ApplyToAllMutations = true,
. N6 c4 O7 A" M        InputArgumentName = "input",
9 A0 G2 j. g3 G        InputTypeNamePattern = "{MutationName}Input",5 d- U; x2 n) s3 N
        PayloadTypeNamePattern = "{MutationName}Payload",- |- X+ x2 G% k- D3 I
        PayloadErrorTypeNamePattern = "{MutationName}Error",0 `: h3 o$ O, {& p! ]- [3 n2 i, M5 u
        PayloadErrorsFieldName = "errors"
3 ?' B* A, \* z  O3 q: ?    })
& m9 \6 I2 u4 L$ W3 m% z1 F    .AddType&lt;PostType&gt;();' ?. n1 M# w5 m0 @/ s- d; V, _
</code></pre>$ Y5 ]5 E$ h" d4 y$ V3 q5 O' s) g# e
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>( r- h8 s: p& Y  A) _6 B
<h2 id="验证">验证</h2>
0 C( J" ?; C+ Y+ }& W" o; k/ R& l& u<p>启动<code>Api</code>项目,调用接口:</p>) G' D7 U8 c: {
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>7 z: z3 C) R* A" j9 t
<p>终端的日志输出如下:</p>4 J! v8 _$ x) Y+ W4 R
<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']; k. }7 C2 z$ ~& Z
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
! c9 v: R4 ~9 wVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);' _# s9 @3 E7 ?6 M
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
* S1 C4 H- g1 Q</code></pre>
% Q- B( m" a: b) Z( m% H* C, |<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
/ B, Z6 K. `4 e' M<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>( D. T  j/ N. a  m6 \7 E& w$ r
<h2 id="总结">总结</h2>. h+ m: L# N- ~
<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>" y. P2 ]& D% G; }& X8 {* z
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
1 a1 u. J( K1 T9 Z1 [
8 N6 h2 U' A. H. S: Q* C. L
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-24 18:24 , Processed in 0.088748 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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