飞雪团队

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

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

[复制链接]

9321

主题

9409

帖子

3万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
30293
发表于 2022-2-12 14:35:41 | 显示全部楼层 |阅读模式
" s, t8 Q9 ^/ b$ }' @  H2 s& B7 _, T
<h2 id="系列导航">系列导航</h2>
" Q: T( ^! b8 m+ l6 K- ]<p><a  href="https://www.cnblogs.com/code4nothing/p/graphql-net6-0.html">使用Hot Chocolate和.NET 6构建GraphQL应用文章索引</a></p>
5 H" I% b+ g9 k9 ~, V& V<h2 id="需求">需求</h2>- @" ]7 E5 C2 g9 y, ?: k
<p>在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务。</p>4 P+ I( Y0 {/ ?# ?+ @" H  l
<h2 id="思路">思路</h2>
) R- v1 }' \$ S, @$ ]0 S% }<p>在GraphQL中,对数据进行查询使用<code>query</code>,而对于修改数据则需要使用<code>mutation</code>,包括新增和修改数据。Hot Chocolate在使用Mutation的逻辑上和使用Query的基本一致,但是需要根据需要定义用于创建或者更新的数据对象,所以我们直接进行实现。</p>
% B: x' B6 A1 ]<h2 id="实现">实现</h2>
! A0 z/ S* m# G/ s/ Q" A) A+ @- A: r<p>为了保持简单,我们先定义以下两个类型:</p>
8 o; @$ ^6 T, j* m2 W' ]<pre><code class="language-c#">// 定义新增Post的参数! M0 Z) L$ v1 R7 }" y
public record AddPostInput(string Title, string Author);
# G" a4 {- a/ U2 z1 `# U  a6 {" l: A# T  t4 o3 Z
// 定义新增Post的返回对象- a$ [2 g( c  X: x' Q' A
public record AddPostPayload(Post Post);
2 e# @" E% _4 f( d</code></pre>2 X2 H$ d2 n. R+ X! {7 W! X
<p>新建<code>Mutation.cs</code>用来定义相关接口:</p>
! [7 m( ]* [# j, l4 n, d; d0 L# _<ul>
0 R  z6 G3 O) J# Z# ]<li><code>Mutation.cs</code></li>
* C! r* v7 P( D2 {) x</ul>- l% g7 b5 J; r8 ^/ B$ N' [
<pre><code class="language-c#">namespace PostGraphi.Api.GraphQL;+ d3 o6 u6 k$ _/ s; p: f

1 q3 V7 T( b/ ^8 K2 @8 y' ?; S5 Qpublic class Mutation
6 g3 b6 _7 |. M4 u' C% F{
) d8 N# d% h  [6 ], S3 j    public async Task&lt;AddPostPayload&gt; AddPostAsync(AddPostInput input, [Service] IRepository&lt;Post&gt; repository)
/ t& E6 q& T% u: |& e% n    {
0 |, L8 P* H, `; g7 g, E4 p        return new AddPostPayload(await repository.AddAsync(new Post
4 y) Q+ @4 g( N  q. L/ r( \        {
" F: {6 u+ |1 h1 c) g. L3 \            Title = input.Title,0 F# [7 X4 `8 X8 M$ v
            Author = input.Author
9 i- X8 S) E. j9 K: h        }));
( v6 \2 E$ k' K    }
$ d1 G/ N: s& S; K, _, H. F* M* z, K}$ }# `3 p6 o$ v

4 J+ b: Z9 y" J5 M4 F</code></pre>
( M- L+ }$ v  E7 g<p>最后在注入服务的地方进行配置:</p>
2 x$ E! u" ~0 D1 l& J<ul>0 J  L9 r3 A. r1 a8 W
<li><code>ProgramExtensions.cs</code></li>
9 x# G* `; e- T/ [</ul>* M2 F6 N& Y5 `1 v+ @
<pre><code class="language-c#">builder.Services
1 ]7 ^% n+ k4 K5 Y4 g8 E2 q    .AddGraphQLServer()' G& V* Y  Z, y# H  z0 i% x+ e  {
    .SetPagingOptions(new PagingOptions
, h% g' l: X/ i1 l# L. E, F/ A    {
2 g% L( Q! Y. V3 Z: b        MaxPageSize = 50,* o: t0 T* i1 w' t0 z
        IncludeTotalCount = true+ `# [. v0 r: |6 D
    })# o4 [0 h6 ?5 p( |/ z) u8 T
    .AddFiltering()
. I+ p' T; v! F! f3 ?* v- }    .AddProjections()
* a( w* F4 r; N4 k. A    .AddSorting()  G6 a6 F0 s& y
    .AddQueryType&lt;Query&gt;()+ D6 ?+ L7 I; `
    .AddMutationType&lt;Mutation&gt;()' k, p, c& c" P( i: `
    .AddMutationConventions(new MutationConventionOptions$ D- q. w9 Y$ R) X; k! y& f
    {- z7 }5 [* \5 S; _
        ApplyToAllMutations = true,+ F6 w* s9 g$ x
        InputArgumentName = "input",. L% d' v9 ]( u- ^
        InputTypeNamePattern = "{MutationName}Input",
& W* ?0 V, ?0 c' n( B6 b" V        PayloadTypeNamePattern = "{MutationName}Payload",
, [- `, i% _/ u- _        PayloadErrorTypeNamePattern = "{MutationName}Error",
1 k% r0 \5 L5 q( k+ f        PayloadErrorsFieldName = "errors", a5 M" m6 X: Q4 F9 ?2 Z* _% c
    })9 w( E3 A, l! g1 S  |
    .AddType&lt;PostType&gt;();: e6 K! t) x, V4 j9 D/ y
</code></pre>- q7 a& U8 ?7 d
<p>这样就实现了新增Post的需求,下面我们来验证一下。</p># b# a$ M! B/ u9 s
<h2 id="验证">验证</h2>
5 w  W- O( @, ?2 C9 M8 Z# L<p>启动<code>Api</code>项目,调用接口:</p>4 R( b' v! ^" c
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104544617-1400586374.png" ></p>
* h: l4 w' p* N) _% m4 h6 Z/ e3 X& c<p>终端的日志输出如下:</p>
/ A( G  ^0 m$ Y: S  s3 g9 }; 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']* j/ q/ }2 F- `! S% e' u  L3 R
INSERT INTO "Posts" ("Id", "Abstraction", "Author", "Content", "Created", "CreatedBy", "LastModified", "LastModifiedBy", "Link", "PublishedAt", "Title")* L! O( F2 Y2 O% l( h0 Y
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10);- T/ C; [( {* o' w) \) `' b
[10:45:15 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'
, J+ F2 r/ j! x, x</code></pre>
5 m' s# |6 b& K9 \: p5 j<p>可以看到新建的Post已经存储到数据库中了,我们可以通过查询接口来获取详情:</p>, D2 \3 W* ^( N9 n0 {7 ?) X% o
<p><img src="https://img2022.cnblogs.com/blog/2487237/202202/2487237-20220211104851825-1533915064.png" ></p>. t! z( w5 q& u9 E1 g
<h2 id="总结">总结</h2>
# {; F" N  `( K  T. U; W<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>. C3 n0 @% ~" G$ b1 I
<p>在下一篇文章中,我们通过<code>Mutation</code>对已有数据进行更新。</p>! m* m2 R9 F! l4 R9 A5 v

) C, k& F2 _* l) e
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2026-11-5 14:24 , Processed in 0.064116 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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