飞雪团队

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

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

[复制链接]

8038

主题

8126

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26444
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
4 {( f9 r7 F+ W) {  A. f- q1 f; v  }4 i
<h2 id="系列导航">系列导航</h2>7 }) }9 t$ e) }
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
+ G: F5 x2 _4 B3 T<h2 id="需求">需求</h2># M* h" m/ t* J! G
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
/ `7 V/ `, O: b6 k5 _6 f<h2 id="思路">思路</h2>
, D' K# \2 U  G$ [; Y<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>' j; Q: c* [/ ^6 C; T
<h2 id="实现">实现</h2>/ Y$ ~; u5 N' T' q8 {
<p>为了保持简单,我们先定义以下两个类型:</p>& ]7 t. N( O  L/ V7 `& B0 t
<pre><code class="language-c#">// 定义新增Post的参数
' Q* O3 Q5 n3 U& V5 k- @public record AddPostInput(string Title, string Author);+ \2 r, i4 s5 ^
; v4 G$ k  I  l
// 定义新增Post的返回对象
/ ]" n6 P0 s  ?! s# W* [8 W; b6 w! Xpublic record AddPostPayload(Post Post);
( A. m& a5 w  c# T$ `9 s+ R</code></pre>
9 n8 q5 t6 G7 P8 h! A' ^* K<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
% W) Z3 F2 \4 ^7 h0 Q7 D7 v- Y: v<ul>" a6 w5 _. H; |- @( W% R6 N
<li><code>Mutation.cs</code></li>
1 x5 a/ o/ v/ V; Q' _</ul>4 T! ]1 D+ u5 q. ~0 C
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
! ~" J% Z! Y7 z  ~7 D9 _. ]' r4 z& _, Y
public class Mutation
3 i# P* \" \: J# \6 g2 ]$ R{
2 U9 k) ~. y) ]. h    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
* c( A7 Y3 D2 t. ~* s/ J9 B    {
0 T& R9 C2 z1 `  E( I. V8 M7 {        return new AddPostPayload(await repository.AddAsync(new Post
6 E( {' [- E8 F5 r* s' c8 E        {, {$ F. g- y7 J7 [  _' a' [& Y
            Title = input.Title,
3 s& g- C) Z. G; v# @, T            Author = input.Author
9 p9 t# M: T0 I# R8 r        }));
$ J# m' L0 D5 i1 I8 J/ Y7 |    }
: L! e( J/ y' n; s}3 L/ d$ o# c+ R  B* Y0 M8 s. S5 H* P/ a
. @8 w; b, p* S( \3 b9 c
</code></pre>
3 G9 Z; a4 m" f6 H# E) }( F<p>最后在注入服务的地方进行配置:</p>: B0 C3 i9 I% f  ]( c3 f1 e: j0 a
<ul>
) k. u/ r7 h" z1 G% g: _  p<li><code>ProgramExtensions.cs</code></li>: q8 k. P% @1 s3 g7 `
</ul>" G6 E2 q" w, a0 G* B! z! L% E! |
<pre><code class="language-c#">builder.Services6 V' F  p( r) j0 _7 n
    .AddGraphQLServer()& l$ N( F3 p8 G2 ?6 E/ h4 j
    .SetPagingOptions(new PagingOptions- P9 R) g1 B) |3 S- [
    {
. V8 S2 a  O% R7 m) o' _        MaxPageSize = 50,9 b3 R: \" C: S+ u" ?
        IncludeTotalCount = true4 Q! J( V  X4 L: r
    })
7 C# _) \( Q, m8 \5 h- a    .AddFiltering()! m* w6 I2 ~9 M) F* z: b6 Q" ^
    .AddProjections()
* W. P, f6 `# m" b+ E( E" |    .AddSorting()
' U5 z9 `* @; e/ T    .AddQueryType&lt;Query&gt;()1 A4 T2 Q5 g, u: D( d. r  O6 u) u
    .AddMutationType&lt;Mutation&gt;()
# j+ ?1 T2 t' m% E3 d3 b  u& ^- c* u    .AddMutationConventions(new MutationConventionOptions6 a' Q# E' z, G) s
    {
  W1 A( o# _5 y5 I( ~9 T        ApplyToAllMutations = true,
8 p4 X  h! |' l5 e9 g' w4 y        InputArgumentName = "input",0 P& _# D0 ?( d+ c
        InputTypeNamePattern = "{MutationName}Input",
( M0 P2 e  U3 M5 j3 p  g# C        PayloadTypeNamePattern = "{MutationName}Payload",# a5 H8 S& A; T' I7 l; ?( a
        PayloadErrorTypeNamePattern = "{MutationName}Error",7 I. x/ p. f+ }5 A3 X( e2 w, l7 @
        PayloadErrorsFieldName = "errors"5 l+ K" g8 z2 n" q
    })$ g" {4 H3 S! {" D
    .AddType&lt;PostType&gt;();. r7 c/ E3 Y6 c
</code></pre>
2 u) W  U5 i# W3 {<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
, u9 z9 j! U+ Z) `<h2 id="验证">验证</h2>5 B  v/ P& I6 Y5 Q
<p>启动<code>Api</code>项目,调用接口:</p>/ m2 @2 |6 K) K2 i7 P
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>/ i# G9 h2 k. Y8 N6 o
<p>终端的日志输出如下:</p>
* a* C8 h* @! K; m. Q) 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']
& O& s; y4 b) c0 y2 K' e* g/ R9 z+ }INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
" w' z: ]- V8 R/ z3 j/ b( E) [% yVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);, p" G" h4 ]8 Y. }7 H
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
+ D3 w2 P5 Q( n! @* R* a</code></pre>
) E/ B% b' C+ ]7 ^* o/ y) d, ~<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>' D3 s; Q0 U. g8 p- a; w
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
4 y0 d5 x$ |' ^8 i<h2 id="总结">总结</h2>
% G% R* r( d- s4 U. j# h7 c<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>( g% v: K( ^9 u  h! \) S' D' E
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>/ R4 i: m) ^2 c4 D9 B! x4 b5 m# z
9 c% {. g& E$ Y
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-5 21:25 , Processed in 0.117792 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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