飞雪团队

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

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

[复制链接]

7952

主题

8040

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26186
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
- f+ L# d# I$ I/ N5 @
<h2 id="系列导航">系列导航</h2>
* `* E7 H( F+ H9 _2 }) P8 x5 o<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
' k, Z6 _6 Y% x: N<h2 id="需求">需求</h2>
: P  Q  k3 \& ~' `' P, x<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>0 O* T8 S" W% c2 Q4 ~6 a
<h2 id="思路">思路</h2>! u( a+ [4 i# z' J
<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
/ M5 H% O& G( l' D& B8 ?<h2 id="实现">实现</h2>
9 v# G% ~% S2 `7 V0 L3 z+ I<p>为了保持简单,我们先定义以下两个类型:</p>
5 P) ?' N- m" Z* k9 o& B<pre><code class="language-c#">// 定义新增Post的参数6 |+ ~9 f( u0 c7 j! g; ?
public record AddPostInput(string Title, string Author);7 ]: @8 t& A# U4 e$ \4 T

! n) K& }, v1 ]// 定义新增Post的返回对象4 B+ b$ d7 j8 `* T$ I7 r
public record AddPostPayload(Post Post);
4 M% l6 n# A" ^! ]: n</code></pre>- m8 O) f/ j! @" r, K/ j
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
& c1 ~" @$ x: D2 T2 X<ul>" S8 e- N6 z! l% T) G  j2 _
<li><code>Mutation.cs</code></li>+ L. s; T% B8 R1 i( S: s! z, ^
</ul>/ C! m# I! y( F. H% d
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;( @1 W( g8 Z" d6 |4 ^5 J9 u
8 G& C1 s* S" r3 S: B$ H) J2 s
public class Mutation! U9 p9 E2 y7 M! u
{
! q! ]  x0 X7 X  U7 z0 E9 D    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)' P9 t7 \3 R8 Y
    {
! a5 Y- @) G" K) H, K        return new AddPostPayload(await repository.AddAsync(new Post; t$ H2 q0 N9 [" p- T& t
        {$ x+ ~5 V0 s% n6 W( M, E( w
            Title = input.Title,5 }# Y/ I+ h" }# }  x
            Author = input.Author
. v/ W; k$ l9 r/ O$ S; ~/ a4 W' Y. C        }));9 Z  ]' u, M- {
    }' q/ I$ Q8 A" z
}+ |, g( [( W' w7 B8 Q, E
4 Z# c! s, T  ?8 R% _
</code></pre>1 L3 B9 q' {( @% T* C
<p>最后在注入服务的地方进行配置:</p>% i1 I' ]& b+ t& q1 t: r$ I% a
<ul>3 `9 O! @6 b1 g  Z  d8 m' H
<li><code>ProgramExtensions.cs</code></li>. P' R  U! G! U# r
</ul>" T( |$ k9 V1 a" f# H3 c/ ?; C
<pre><code class="language-c#">builder.Services
: W' r& s% D6 b    .AddGraphQLServer(); {0 e) |: D2 c6 u9 Q" ]
    .SetPagingOptions(new PagingOptions: c8 o9 H. V9 C- O
    {( R1 o! u0 q6 J, \4 y- U1 _
        MaxPageSize = 50,- a" B9 h; ~  [1 Y9 j
        IncludeTotalCount = true
! b( a+ S5 n' i5 C    })* Y$ B) w. O; c' V, l( a
    .AddFiltering(): T  p+ K: Q4 C6 [, O4 l
    .AddProjections()
  `. w* y0 U- M, _& E    .AddSorting()
/ y! V4 p$ l3 Y6 R# S    .AddQueryType&lt;Query&gt;()
- a0 w% V& w/ ]9 [    .AddMutationType&lt;Mutation&gt;()" ~1 n% ~2 H- @' T6 Z' E
    .AddMutationConventions(new MutationConventionOptions
3 s1 h8 {) v: }, f: Q- S    {8 \$ ^  o: _6 b# t6 E7 n. t, B/ ^% {- b
        ApplyToAllMutations = true,
* Y' e( z0 i; x2 t" W. E        InputArgumentName = "input",
8 V" f* {2 E" q: X9 i        InputTypeNamePattern = "{MutationName}Input",* b* p- R( \9 G$ l$ P- V; D& x+ j
        PayloadTypeNamePattern = "{MutationName}Payload",
) v! Y$ P. h3 O8 O9 h( A" ]        PayloadErrorTypeNamePattern = "{MutationName}Error",
# |0 P- r- L# A" ?5 @4 P# n5 \        PayloadErrorsFieldName = "errors"
6 A  J- j/ b; v" N4 ]: T    })2 b3 Y) r9 N! c1 i
    .AddType&lt;PostType&gt;();
; @( n& Y" K4 I: m% c6 Q6 l</code></pre>
% A3 K$ P& }& Y; ?* X) Q% _<p>这样就实现了新增Post的需求,下面我们来验证一下。</p>! w% ~" O& i" S* `; h$ i
<h2 id="验证">验证</h2>$ B3 V# M* P$ Z, b3 g; A+ L
<p>启动<code>Api</code>项目,调用接口:</p>
( G$ i6 z% j0 Z) }! g<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
# D5 Q' a; o1 Z" b! I<p>终端的日志输出如下:</p>8 @6 [. L( F  C+ F( l
<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']
, K8 q: Z; D1 w6 `INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")
2 D+ a! T. q; g' a5 m& b9 KVALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);, N, S5 |( z, T7 N; J( |
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
9 s; ]# j: [2 n" n</code></pre>- {) r1 k, o6 V4 H5 Y
<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>1 {5 w" \) ]1 ?/ N" S! t: p! @
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>
% |& S  a8 c: t3 ?; \<h2 id="总结">总结</h2>
! Q+ {4 \& k5 Q* n+ _<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># @! }: A4 c# l
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>
3 S& N' ?  O7 l) v6 T8 G( J9 ]; G& a# b+ ~7 Y! G1 E
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-23 14:32 , Processed in 0.065029 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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