飞雪团队

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

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

[复制链接]

6382

主题

6470

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
21470
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
8 O) f' L5 S- e
<h2 id="系列导航">系列导航</h2>
1 Q8 i, u6 ~! ?9 q1 v; |& M* v: f<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
& u9 P' Z* v# q: c<h2 id="需求">需求</h2>
& k' S. P* k8 H<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>4 N9 o( r2 P' l! i4 @! [+ v
<h2 id="思路">思路</h2>
, U) X9 B4 l' ^4 A) h# }<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
$ Q3 P9 [5 o7 ^" p  F2 R<h2 id="实现">实现</h2>4 x( J: @& \' m- U1 q& s- {% d
<p>为了保持简单,我们先定义以下两个类型:</p>
4 y' C( s/ `! c; s) ~<pre><code class="language-c#">// 定义新增Post的参数; [4 s' H1 i1 {$ N9 r$ u
public record AddPostInput(string Title, string Author);* s0 I9 ~  R- K7 P# }! D

7 B& z, m! Q( {, {// 定义新增Post的返回对象
: n5 z) ]* {8 _; Xpublic record AddPostPayload(Post Post);  v$ _4 N) D. L- k+ S. v6 l
</code></pre>9 Q, W1 ^* I6 b# s
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
* y% z" v2 i$ @% |<ul>5 r3 B& q* |# K( j4 H6 b+ G
<li><code>Mutation.cs</code></li>
  K4 i4 o/ B* x/ w. [! R1 `</ul>6 W0 `  H& c: x, k2 `* ^
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;
, l. _( o0 q* }
# u& [4 d  V  c" I9 M( {, Spublic class Mutation
9 Y1 i% m! s1 |% z{
  M9 D* R& K" ~( y7 f    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)$ E% d6 D6 R  [2 S' E
    {
: E7 y$ L! I+ g4 X- L; j3 ~        return new AddPostPayload(await repository.AddAsync(new Post
3 W& \/ H+ f7 {: R5 ^' [5 k8 P7 n        {& N) U' n, g/ {" |9 w" H% l6 {
            Title = input.Title,
+ Z2 }/ p  Q" H. j            Author = input.Author
  H% H; A' ]; @2 Y- D8 H        }));' e! r: N* c4 _3 y/ y( h( G0 n
    }
; F* a  i/ _6 m/ o) }* _; Y0 [}  y* t7 f2 D3 }+ q

. X5 d3 {  E" ?: `, a  g+ D& t2 |</code></pre>0 M5 @( z3 a9 B% o/ \
<p>最后在注入服务的地方进行配置:</p>
# ]. l0 p( w$ U* C<ul>
1 b: ^' q9 d! }7 o* |<li><code>ProgramExtensions.cs</code></li>
1 h6 F' {4 s9 {  M</ul>; f: q6 w! z7 X4 m
<pre><code class="language-c#">builder.Services& J% P. p# M2 w
    .AddGraphQLServer()
/ }" t, Y% k: n; H1 G* i    .SetPagingOptions(new PagingOptions
: Y2 p' ]( ~/ o9 a    {+ ^0 s8 v% ]" f# R
        MaxPageSize = 50,
  T% d. ?/ |0 r$ ?9 [        IncludeTotalCount = true
7 E" u. S  V, _2 [8 O4 [    })0 t: w! W! q. d5 y
    .AddFiltering(). ~' Z+ `/ W6 M9 \
    .AddProjections()
' L. u1 A* E1 _- C2 w1 ^* R- O    .AddSorting(): |+ {2 W. t# x! J
    .AddQueryType&lt;Query&gt;()
' y) i8 p: i. {& s( S/ P    .AddMutationType&lt;Mutation&gt;()8 H0 v- [2 r/ |7 E. H0 W# h$ E& X
    .AddMutationConventions(new MutationConventionOptions0 }/ Y2 B6 l7 i) s, @; H
    {
+ N! J: B0 q- b& ~4 \6 E# A# Z        ApplyToAllMutations = true,; J1 {, D( ?  F" F" n/ B
        InputArgumentName = "input",
3 {9 m6 L& ~8 j        InputTypeNamePattern = "{MutationName}Input"," q" C- v8 ^- a$ y. b
        PayloadTypeNamePattern = "{MutationName}Payload",
- {' @% C% O1 k; q$ G; M/ g& l        PayloadErrorTypeNamePattern = "{MutationName}Error",
: Z% u" t" p7 ?: E% ^& |        PayloadErrorsFieldName = "errors"2 H0 J) L& v8 T% D9 c* N; y
    })8 o* F+ {2 t2 B; j7 T9 J# K( {
    .AddType&lt;PostType&gt;();( Q) F9 j( Q; A* e" O4 `5 {% E6 `
</code></pre>
# A" Y# P5 d3 t2 ]9 R6 N  _' `<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>7 N4 j. }3 x/ l) f/ [
<h2 id="验证">验证</h2>
! Y) [  h+ N; @' j! P' w$ @" E. D<p>启动<code>Api</code>项目,调用接口:</p>
+ b+ C% A  s9 ?$ n  A+ G<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>/ b+ F) r) ^; ?. H& U
<p>终端的日志输出如下:</p>7 k* V* S$ ]0 j
<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']
' R  H8 T/ E$ ~: Y  lINSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")2 q0 O( S4 o$ u$ B. C7 \2 b2 [1 k; w- ~
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);
- `3 A8 s6 z9 N+ E% Y% w" P9 r1 [7 K[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'4 J- s0 m' ?! \! J. K
</code></pre>
: L  C, W7 Q; B  {<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>
1 x8 u& B2 L- I3 _4 O0 I$ m<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
$ y1 P& K( b8 {) j. e, E/ f$ O<h2 id="总结">总结</h2>
9 O# u; ]% H" ~<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>
7 y" N( |' z% B  \<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
5 V. a# Q5 b' I) a8 S0 M3 J3 S
5 k+ M3 O, @9 T  a; e* p/ P! F' C7 A
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-4-19 10:41 , Processed in 0.062897 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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