飞雪团队

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

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

[复制链接]

8087

主题

8175

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

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

! `1 q% o* l( o+ S7 b8 Q<h2 id="系列导航">系列导航</h2>) U6 w$ T6 b# W2 o' \
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>2 O* r+ r+ M& A# K) o
<h2 id="需求">需求</h2>
( y$ d7 I8 c4 j2 ^( N. n<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
4 A- a0 m0 h" e* _6 L" L# f1 y<h2 id="思路">思路</h2>6 o6 m8 Y4 Q4 Q
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>" |7 U, ^8 ?! u! x7 i- U6 I  A
<h2 id="实现">实现</h2>- |' M6 F( q( [; ?5 b' {
<p>为了保持简单,我们先定义以下两个类型:</p>
' B( Z6 J" }4 D2 u- b! P<pre><code class="language-c#">// 定义新增Post的参数
7 h9 V- I1 Q  b5 C6 A: s, Xpublic record AddPostInput(string Title, string Author);" p5 {4 h: |3 m8 P( o8 D

9 J4 ]" r0 T( ]- W4 S8 B: g' F// 定义新增Post的返回对象
1 B' s9 {" T% p! I& Epublic record AddPostPayload(Post Post);8 ?3 h  m0 ~7 O7 {  x. d& e
</code></pre>* f. C% }% }7 L
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
' I7 M0 n' ^; B5 b! i" J. z- b<ul>( j$ @0 ?, n4 v1 C2 }! ], _
<li><code>Mutation.cs</code></li>4 ]8 P. u+ L* x" V' n9 V* q1 H; ~/ X
</ul>6 ~/ r& w" h! I
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;$ d: X+ g, x: G, _) ~7 `

; [- P* \, {1 O/ U0 Bpublic class Mutation
4 S' F" R0 C  X* E! j{% m% N  T6 I7 d0 H
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository); T2 J( u6 S( e
    {
6 O# }8 O. f  @; ^% @+ q8 [        return new AddPostPayload(await repository.AddAsync(new Post- |9 n5 K7 N+ K3 E3 V
        {
* E+ T! q% G, v3 |& z            Title = input.Title,. ?- G) v. ?+ b' U; X
            Author = input.Author
3 r4 k( v0 w7 C' i        }));! W' Y8 s( v2 x. L- M
    }8 p, X; P' ~8 r* n8 j
}! h3 P0 Z5 g# A  U9 x
6 p9 I1 @( @8 |: M) q- j; ]$ g
</code></pre>
9 A( v, Q' v% y3 R% c1 m6 z# C, p<p>最后在注入服务的地方进行配置:</p>8 E6 P5 {) o0 y$ {& @/ o
<ul>
2 X) }+ d* a& h2 d; i, P3 j<li><code>ProgramExtensions.cs</code></li>
. @, h5 |( U* Q3 w) h</ul>8 ~/ Z4 r/ }: f
<pre><code class="language-c#">builder.Services& _$ W# t# T/ Q5 J
    .AddGraphQLServer()
: ?7 g3 |$ j# C9 D    .SetPagingOptions(new PagingOptions
1 W4 p% w7 j4 ?# I8 _, X3 i1 r" ]/ h    {6 N& R8 V* ^! A, z- j. B
        MaxPageSize = 50,
8 f8 W- K# [7 G( V        IncludeTotalCount = true
. d1 u, ]- {( P    })- q. r  U' Q- k
    .AddFiltering()
: Q4 c. E  e9 c! e8 R% k    .AddProjections()
: x- m( H9 E2 ]( o- W    .AddSorting()
4 u. g, k+ f' Y, Y4 O  O    .AddQueryType&lt;Query&gt;()  Z: U+ z7 V2 s3 h9 m" K! C6 W: S
    .AddMutationType&lt;Mutation&gt;(), W- H5 ~  S" m4 a% ]+ @& f' Y2 r
    .AddMutationConventions(new MutationConventionOptions
4 l: _+ A( Y9 h4 u- S, w: J7 {  [* Z    {) [& u) o6 I1 x
        ApplyToAllMutations = true,
, Y. n$ H5 N. b9 ?        InputArgumentName = "input",
- F8 ^; K5 |& `  g! w1 K1 A* h        InputTypeNamePattern = "{MutationName}Input",
* N2 Z1 U( ^# [1 P        PayloadTypeNamePattern = "{MutationName}Payload",
- f5 Z5 G5 B  p) i- E        PayloadErrorTypeNamePattern = "{MutationName}Error",
+ B- Q( D8 x$ c( ^0 M" P        PayloadErrorsFieldName = "errors"
- p/ N8 C7 x5 E    })
+ [% V1 M8 c5 u$ Q* L. y    .AddType&lt;PostType&gt;();, ], O+ R  {% }; e5 u% {7 q, f. G+ \3 P
</code></pre>9 x: `+ v1 ~, J3 i" a0 X  r
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>6 B/ T) ]9 K; s/ q9 `" H5 G. g
<h2 id="验证">验证</h2>/ e* z( d/ ?6 ]; p! ]+ z
<p>启动<code>Api</code>项目,调用接口:</p>7 x- {% C6 G. a% t
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>$ B$ U) B( u; L0 T0 A
<p>终端的日志输出如下:</p>6 m  C% d5 x8 G4 A, N; 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']  p. t+ [$ E% ^6 X$ I
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
2 w; }5 L( b0 F+ GVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
2 J5 p0 c! I/ |6 W[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'" z) Y+ L0 m5 g( V( S3 `
</code></pre>
! Q, ~+ n7 `* M3 l) m<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>( {4 w. f4 |1 G, C8 B8 \3 ]
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>8 S& V5 H# v* b6 ~9 Z; b  f4 Q
<h2 id="总结">总结</h2>  V5 v$ B& \# I
<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>! ^& l7 x; A) y1 N: q" }/ _! Q' \
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>6 d/ j4 ^7 W  v" l

; y2 {) s; c$ ]
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-17 20:01 , Processed in 0.117079 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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