飞雪团队

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

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

[复制链接]

8042

主题

8130

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26456
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
3 B2 Y+ k' M1 Y3 z! j5 t2 b, r0 J
<h2 id="系列导航">系列导航</h2>. h, B& ?0 T/ i4 V
<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
5 O: D9 _" E9 J. W0 u- O& h( B7 I<h2 id="需求">需求</h2>" ~- P# E3 G3 c
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>
% l' g2 M$ o0 K4 }<h2 id="思路">思路</h2>
! Z5 P5 ]; ]3 a6 [- U<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>) G5 M' X3 B5 H6 J0 D( y
<h2 id="实现">实现</h2>2 z2 V* N& \- b* T+ p* L* W
<p>为了保持简单,我们先定义以下两个类型:</p>+ U9 h$ h2 V, V7 P4 n0 q* m
<pre><code class="language-c#">// 定义新增Post的参数2 Q' W. F8 N: R( F* S6 J
public record AddPostInput(string Title, string Author);
; F# A3 B$ }4 F
/ ~' z$ W8 w, s- e// 定义新增Post的返回对象
, P# F( j, q6 A8 p4 z, J% q1 ?& Cpublic record AddPostPayload(Post Post);
/ z+ v5 w+ {2 E( e/ h  [- y' }- J3 O</code></pre>
+ g- J+ c$ @' K& |! q! R+ W<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>4 F7 w& J# ]- S4 o7 \6 n% f+ B
<ul># e# G4 m4 Z- O  O6 O
<li><code>Mutation.cs</code></li>7 A6 [. N8 _2 Y# }( M- {, @" i
</ul>% i) ~/ v# x5 n2 l2 S& \4 }5 U7 V
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;' {8 E6 B# A8 G6 w1 ~8 c& y
% T6 f. r) D  }. L0 u
public class Mutation
* V1 C! E  L% {% C2 C8 L3 d! E8 f{6 Y& ~$ y' r0 O; ~
    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
8 H1 f0 M/ }% D% g. S0 _& {    {
8 y5 }' ?9 A/ c+ c) z0 Y        return new AddPostPayload(await repository.AddAsync(new Post
# L; P! d8 _* P, w( K        {
. B. A/ w+ H, f9 u! l6 {            Title = input.Title,
# R7 p8 N( N8 D0 u0 b) G. D# K            Author = input.Author8 v0 w* z* ]( m- K
        }));: i9 V0 ?# m# B6 K1 a# c. M
    }2 t( W0 s& e7 |6 f5 N6 M
}2 j  p6 {7 _/ ^

; o/ u4 j+ t& R2 f4 T' B5 O</code></pre>
8 Q4 n( b' S9 [6 W/ ]3 Y<p>最后在注入服务的地方进行配置:</p>1 N! y9 r& a+ ?/ J% S2 r
<ul>
8 K% w. G% H5 ~- F3 P<li><code>ProgramExtensions.cs</code></li>
1 Y* V9 T( ]' W  m3 m5 V4 O</ul>
7 I2 ?. r9 y3 n<pre><code class="language-c#">builder.Services
# p3 q- B+ m1 c0 q% C    .AddGraphQLServer()% u6 D5 }, Z: K3 m. O/ y
    .SetPagingOptions(new PagingOptions
, {5 \3 J  U5 ~7 h1 A; I1 L    {
: S7 h$ B( i$ x        MaxPageSize = 50,
9 D6 d& t: V* I6 v2 _5 s        IncludeTotalCount = true! |0 b, {: n3 S4 M) `( D: w0 i
    })
, R6 q( o, p, M7 m$ ~5 R    .AddFiltering()
% p! Z# p% p& D    .AddProjections()$ ]+ G/ x% b; x/ {: j3 }/ |
    .AddSorting(); f* r) T4 B; R. z& n
    .AddQueryType&lt;Query&gt;()
7 e" W5 Y9 Z; m7 M. l    .AddMutationType&lt;Mutation&gt;()) [' a4 m7 s. ~* W  y! T
    .AddMutationConventions(new MutationConventionOptions, V5 M& E% F# F9 T, T
    {% x8 ~: H( ~+ S; S1 P
        ApplyToAllMutations = true,$ Q$ O- W4 }3 P% n+ T% [
        InputArgumentName = "input",9 R5 v: {! d2 r: i9 l( b2 A
        InputTypeNamePattern = "{MutationName}Input",& o8 z" c+ {3 {3 w* L
        PayloadTypeNamePattern = "{MutationName}Payload",
$ f! Q( g# ]/ i$ s! \2 l        PayloadErrorTypeNamePattern = "{MutationName}Error",; V! @  z0 r9 Q" ?! ~5 c
        PayloadErrorsFieldName = "errors"
6 k- U* T  H+ X' B( ^1 q4 H" u    })
  I( \& {5 A6 Y4 C9 |: J/ m5 w    .AddType&lt;PostType&gt;();
" J* \4 N' p4 e</code></pre>
7 q. R# }5 z7 a9 ^<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>
" m" }8 `1 d, p, P5 ^* X<h2 id="验证">验证</h2>  F2 k; z; B0 e" K6 p; y: e
<p>启动<code>Api</code>项目,调用接口:</p>4 ~/ G9 r# {1 J* o2 E+ b. S$ v  X' `6 w
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
! \# H* Q% |' W<p>终端的日志输出如下:</p>$ S/ Z4 _0 L% v, ^( h
<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. X! g! p: }" b; CINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title"); \. M1 d: p& T4 A0 g7 c
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);4 a" F6 M, L" j* ?/ d. L4 E- R
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'9 s: a. ~) r. v" `3 ]6 [/ W
</code></pre>
$ U! v  _4 u  A& S7 B<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>/ h( P0 ^- _5 k, @  R% m5 [% b
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
0 {) D$ o6 P2 ?6 j" U<h2 id="总结">总结</h2>
" a7 w# v! t  k  a<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>' K( X' o3 \2 p6 z
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
" y8 Q6 O5 F3 P5 X; e8 w2 B  x8 ?& O% B6 h  W" C7 J7 A
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

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

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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