飞雪团队

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

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

[复制链接]

8123

主题

8211

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26699
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
( G6 D# C+ R; K2 ?6 t$ W, b1 g
<h2 id="系列导航">系列导航</h2>( \% E5 X5 b+ p  [2 s! [
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>  I7 A1 ?% o, _1 P, ^. @' w; ~
<h2 id="需求">需求</h2># {: }1 T9 k$ Z0 ^+ D# [' ^3 }
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
5 G3 j6 L) D& [0 d# y  {5 D<h2 id="思路">思路</h2>/ F/ L. D6 }$ T9 A  [9 B& g. G6 q
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>' X; R5 Z/ U- m8 S" I) m. K* E
<h2 id="实现">实现</h2>
: j0 R# F( c& C! M2 \8 F( {* z<p>为了保持简单,我们先定义以下两个类型:</p>3 v. u# N( E7 \1 |6 O
<pre><code class="language-c#">// 定义新增Post的参数0 S, T8 R! o; e, g6 J
public record AddPostInput(string Title, string Author);
& X) ?/ c) L+ R* A6 J& |+ H1 w. Q) p2 O" o1 j2 p
// 定义新增Post的返回对象
; B4 d4 C; d  Dpublic record AddPostPayload(Post Post);9 q/ s! Z! _/ ~
</code></pre>% ^6 {! E& k' U8 g, w' \4 `; O' P/ C
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>( b$ [4 Z& [* v: S- R
<ul>
1 J* E( }+ n/ _7 Y: U0 W4 `<li><code>Mutation.cs</code></li>
( b4 B9 i: |6 ^; |2 T</ul>
/ x: P! M0 P1 `, z! i  c<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;" Q+ ^; B' @- n
; Z% q+ j, ~; h6 q3 W0 W) `
public class Mutation8 ?5 z* I5 A' F2 i5 b8 ^* _
{
7 H3 }7 A: y5 U1 f; ?# z; \3 t    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)- l. s4 Z/ _4 W* F2 W  j. h4 s
    {% G8 V- Q' t5 i' {
        return new AddPostPayload(await repository.AddAsync(new Post
2 m; X  E1 V1 K: l* M( {        {
7 f1 M5 \+ ~* H            Title = input.Title,& q3 X3 C# `6 M$ K2 B  e" m$ ~9 h
            Author = input.Author
3 `/ }- ^8 s/ Q5 U! r        }));( u4 ]7 v% m8 e$ e, ^
    }  [; N. \- X: d* Q  U1 u$ X4 C3 w! A
}1 w  B/ F" E% ?9 Z

4 Q+ A- A4 N& c* S6 q  U6 G/ \</code></pre>( L! M3 h/ H4 m" Z! l
<p>最后在注入服务的地方进行配置:</p>4 g( D7 F3 O- J1 Y
<ul>7 t% a5 D( f( R/ o2 |& m$ w: a
<li><code>ProgramExtensions.cs</code></li>2 l' I( u3 Y# [
</ul>
; R  k, ~7 d3 S' g<pre><code class="language-c#">builder.Services
2 [, n3 r4 K) ]    .AddGraphQLServer()
; [/ _8 p& Y, `) i/ c/ ^    .SetPagingOptions(new PagingOptions* F. N7 L: R2 b! p
    {
- _1 ^2 k. K1 B, I5 R        MaxPageSize = 50,
1 \. w) Y! ]( \+ d0 {        IncludeTotalCount = true$ z+ g- F5 o0 i! u( ~) G  s9 x
    })! x2 R. F/ Q, O2 ^; W8 s
    .AddFiltering()
2 ?* H4 o3 e+ w2 C4 l3 b    .AddProjections()
+ }$ j  x& x! ^- `    .AddSorting()* [) ?9 N8 ~! U" |
    .AddQueryType&lt;Query&gt;()
# m$ A; X+ u: B& |0 T    .AddMutationType&lt;Mutation&gt;()5 Q6 g+ ^8 z& c8 @  C
    .AddMutationConventions(new MutationConventionOptions  W/ A# i6 y- k( P
    {9 H& H0 i  d9 G
        ApplyToAllMutations = true,  a$ V( i4 w4 ]4 ?$ Z' Q: C
        InputArgumentName = "input",
' Z% `3 n9 a0 B        InputTypeNamePattern = "{MutationName}Input",
# r! l& b1 Q7 j! _; _        PayloadTypeNamePattern = "{MutationName}Payload",) q, V3 b" v5 }
        PayloadErrorTypeNamePattern = "{MutationName}Error",
6 N3 G+ ?$ e- s; L        PayloadErrorsFieldName = "errors"( B3 m# L; r4 f
    })
3 S% Y0 z% \. h; B* P    .AddType&lt;PostType&gt;();* S) V% Q+ q/ E3 J
</code></pre>8 G2 t- S$ B8 I, q( }
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
3 Y( m& L; p9 r" w8 m+ I' x<h2 id="验证">验证</h2>
" h8 `. W0 e) S8 J/ K$ o! B2 f<p>启动<code>Api</code>项目,调用接口:</p>
6 b& b" p0 a5 X9 j. d0 e<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
$ U. l) |/ ^) s' a0 c8 N9 i<p>终端的日志输出如下:</p>
6 c' i0 K- W. \) v! n$ R8 H* x<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']/ v7 v4 v- {( d8 `/ }$ @
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
' G8 i$ m+ Y: e3 z5 ?+ UVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);3 D7 e/ N- w) M, a0 |' i8 _
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
- E  s8 w( x4 x1 T3 g' t% p. L3 z</code></pre>. q. P9 d' O' ?1 Y6 G& Q/ {1 B
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>5 l7 Y, e; W9 Q' d4 w* o9 s. r
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>6 B0 d: |$ ]. Y! {! d8 K0 {. @
<h2 id="总结">总结</h2>
' I' w0 i2 C( u) w6 J<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>
3 q' [' I1 }0 k' r5 k- A9 C. X0 |<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
+ c( ^' q; u5 Y6 \% u: l' ^& p9 R/ y) @" c( M
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-24 17:53 , Processed in 0.066325 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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