系列导航

使用Hot Chocolate和.NET 6构建GraphQL应用文章索引

需求

在本文中,我们通过一个简单的例子来看一下如何实现一个最简单的GraphQL的接口。

实现

引入Hot Chocolate依赖包

由于我打算将GraphQL的相关逻辑放到Applicaiton层,并在Application和Api项目中使用,所以在该项目中引入以下依赖包

# Hot Chocolate在.NET Web应用中使用的主要Nuget包
HotChocolate.AspNetCore
# Hot Chocolate集成EntityFramework Core底层ORM框架的Nuget包
HotChocolate.Data.EntityFramework
# Hot Chocolate的一些属性定义扩展
HotChocolate.Data
# 一个可视化的GraphQL Schema中间件
GraphQL.Server.Ui.Voyager

添加Resolver

Api项目中添加文件夹GraphQL用于存放GraphQL接口相关的定义,并新建Query.cs文件,我们在这里定义一个接口:

  • Query.cs
namespace PostGraphi.Api.GraphQL;

public class Query
{
// [Service]是Hot Chocolate提供的用于获取依赖注入对象的属性
public IQueryable<Post> GetPosts([Service] IRepository<Post> repository) => repository.GetAsQueryable();
}

需要在GlobalUsings.cs中添加以下命名空间:

  • GlobalUsings.cs
global using HotChocolate;
global using PostGraphi.Domain.Post.Entities;

添加依赖注入

  1. 添加GraphQL的服务:
builder.Services
.AddGraphQLServer()
.AddQueryType<Query>();
  1. 添加GraphQL终结点配置和Voyager中间件
app.UseHttpsRedirection();

// 添加GraphQL终结点配置
app.UseRouting().UseEndpoints(endpoints =>
{
endpoints.MapGraphQL();
}); // 添加Voyager中间件并配置URL
app.UseGraphQLVoyager(new VoyagerOptions { GraphQLEndPoint = "/graphql" }, "/graphql-voyager"); app.UseAuthentication();
app.UseAuthorization();

验证

运行Api项目,首先我们访问地址:https://localhost:7194/graphql-voyager 查看Voyager的主页:

可以看到我们目前只有一个schema,名称叫做posts,该接口所关联的实体以及实体关联的其他实体组成的图非常清楚地显示出来了。这张图上我们能看到DomainEvents也显示出来了,但这不是我们想要的,这个问题我们稍后来解决。

再去查看Hot Chocolate官方提供的随程序一起启动的Banana Cake Pop主页:https://localhost:7194/graphql/

在这个页面上我们可以查看具体的Schema Definition和全部的GraphQL Server所维护的类型定义。也可以从Operations标签页直接发起GraphQL请求。

query {
posts {
id,
title,
author,
comments {
content
}
tags {
name
}
}
}

如果使用API Client发起GraphQL请求,注意请求是POST https://localhost:7194/graphql,Body内容是GraphQL Query,像这样:

在执行请求之后,我们先来看看控制台的EFCore日志输出:

SELECT "p"."Id", "p"."Abstraction", "p"."Author", "p"."Content", "p"."Created", "p"."CreatedBy", "p"."LastModified", "p"."LastModifiedBy", "p"."Link", "p"."PublishedAt", "p"."Title"
FROM "Posts" AS "p"

敏锐的小伙伴可能会发现,这个sql里并没有看到和Comments和Tags相关的Join之类的操作,下面的通过Banana Cake Pop请求响应也同样能说明这个问题:

在这个返回结果里,我们至少能看到两类问题:一是Comments和Tags这种一对多和多对多的关联表数据并没有同时返回;二是返回似乎没有排序。这两个问题我们会在后面的文章里逐个去解决。

不管怎么样,我们的第一个GraphQL接口已经调用成功了。下面来解决上面说到的DomainEvents的问题。

改进

因为我们默认使用了Annotation First方式去构建接口,并且是直接使用的实体对象,并没有做任何配置,因为我并不想将业务相关的接口属性直接配置到我的Domain Model上,这个时候就需要使用Code First方式去为Post类定义对应的GraphQL类。

Api/GraphQL中新建文件夹Types并创建PostType.cs,让它继承自Hot Chocolate提供的ObjectType<T>类型,并重写Configure方法:

  • PostType.cs
namespace PostGraphi.Api.GraphQL.Types;

public class PostType : ObjectType<Post>
{
protected override void Configure(IObjectTypeDescriptor<Post> descriptor)
{
descriptor.Description("Represents Post Entity Type.");
// 构建schema时忽略这个字段
descriptor.Field(d => d.DomainEvents).Ignore();
}
}

需要在GlobalUsings.cs中引入命名空间:

  • GlobalUsings.cs
global using HotChocolate.Types;

最后在依赖注入的地方添加Type即可:

builder.Services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddType<PostType>();

重新运行程序,我们在Voyager主页上查看,DomainEvents已经消失了:

总结

在本文中我们实现了一个最简单的GraphQL接口,并且使用了Hot Chocolate提供的两种方式Annotation FirstCode First实现了功能。其实关于Code First方式还有一个比较重要的概念叫做Resolver我们在文章演示中没有涉及,这个概念可以理解为通过Code First方式去定义GraphQL对象时,我们可以使用ResolveWith来指定使用什么Resolver去获取数据。更多的配置方法可以参考官方文档:Resolvers

本文我们还留下了两个问题,下一篇文章将会实现关联实体对象的获取方式。

参考文章

  1. Resolvers

使用Hot Chocolate和.NET 6构建GraphQL应用(3) —— 实现Query基础功能的更多相关文章

  1. 使用Hot Chocolate和.NET 6构建GraphQL应用(4) —— 实现Query映射功能

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 在上一篇文章使用Hot Chocolate和.NET 6构建GraphQL应用(3) -- 实现Query基 ...

  2. 使用Hot Chocolate和.NET 6构建GraphQL应用(5) —— 实现Query过滤功能

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 对于查询来说,还有一大需求是针对查询的数据进行过滤,本篇文章我们准备实现GraphQL中基本的查询过滤. 思 ...

  3. 使用Hot Chocolate和.NET 6构建GraphQL应用(6) —— 实现Query排序功能

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 从前几篇文章可以看出,使用Hot Chocolate实现GraphQL接口是比较简单的,本篇文章我们继续查询 ...

  4. 使用Hot Chocolate和.NET 6构建GraphQL应用(7) —— 实现Query分页功能

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 GraphQL中的查询分页相对来说是查询中比较难理解的,接口的Schema也和其他不一样.在这篇文章中,我们 ...

  5. 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引

    系列背景 在进入微服务的实践系列之前,我们一起来学习和实践一下.NET应用开发生态中一些比较重要的技术,这个系列就是关于GraphQL在.NET 6应用中的实现. 系列导航 使用Hot Chocola ...

  6. 使用Hot Chocolate和.NET 6构建GraphQL应用(1)——GraphQL及示例项目介绍

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 前言 这篇文章是这个系列的第一篇,我们会简单地讨论一下GraphQL,然后介绍一下这个系列将会使用的示例项目. 关 ...

  7. 使用Hot Chocolate和.NET 6构建GraphQL应用(2) —— 实体相关功能实现

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 在本文中,我们将会准备好用于实现GraphQL接口所依赖的底层数据,为下一篇文章具体实现GraphQL接口做 ...

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

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务. 思路 在G ...

  9. 使用Hot Chocolate和.NET 6构建GraphQL应用(9) —— 实现Mutate更新数据

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 在上一篇文章中,我们演示了如何使用Hot Chocolate进行GraphQL的Mutate新增数据,这篇文 ...

随机推荐

  1. nim_duilib(5)之option

    introduction 更多控件用法,请参考 here 和 源码. 本文的代码基于这里 xml文件添加代码 基于上一篇, 继续向basic.xml中添加下面关于Option的代码. xml完整源码在 ...

  2. c++代码编译错误查找方法之宏

    1.关于 本文演示环境: win10+vs2017 好久不用这法子了,都快忘了 排查错误,思路很重要,且一定要思路清晰(由于自己思路不清晰,查找错误耽误了不少时间,其实问题很简单,只是你要找到他需要不 ...

  3. 【九度OJ】题目1194:八进制 解题报告

    [九度OJ]题目1194:八进制 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1194 题目描述: 输入一个整数,将其转换 ...

  4. Codeforces 777D:Cloud of Hashtags(暴力,水题)

    Vasya is an administrator of a public page of organization "Mouse and keyboard" and his ev ...

  5. CS5265替代LT8711设计TYPEC转HDMI 4K高清投屏方案|LT8711龙迅替代方案

    龙迅LT8711是一款Type-C/DP1.2 to HDMI2.0方案芯片.LT8711HE是一款高性能Type-C/DP1.2至HDMI2.0转换器,设计用于将USB typec或DP1.2源连接 ...

  6. 带SD读卡的USB HUB方案芯片MA8621|用于带读卡的USB HUB拓展坞方案芯片MA8621

    MA8621是一款带SD读卡器控制器的USB 2.0高速3端口集线器方案芯片,主要用在USB TYPEC拓展坞或者USB typec扩展底座上面. 1. MA8621功能概述 MA8621是USB 2 ...

  7. Android 常见对话框的简单使用(提示信息对话框、单选多选对话框、自定义对话框)

    目录 一.提示信息对话框: 二.单选对话框: 三.多选对话框: 四.自定义对话框: 演示项目完整代码: 一.提示信息对话框: //显示提示消息对话框 private void showMsgDialo ...

  8. 编写Java程序,通过给定可变参数方法,计算任意给定的多个int类型数据之和

    返回本章节 返回作业目录 需求说明: 通过给定可变参数方法,计算任意给定的多个int类型数据之和. 实现思路: 定义可变形参方法,参数类型是int类型. 定义变量 sum 接受最终的和. 通过 for ...

  9. Net 实现自定义Aop

    引言 何为AOP,在软件开发中,总是听到这个AOP这个词语,但是何为AOP呢,AOP全称是Aspect Oriented Programming,中文译为面向切面编程,什么意思呢,即我们的应用程序在运 ...

  10. Java的jar包构建成docker镜像并运行

    结构如下 把jar和Dockerfile放到一个文件,不在一个文件下会报错文件找不到 创建一个构建文件 buildimage.sh vi /home/hanby/buildimage.sh echo ...