使用 Spring Boot 构建 GraphQL 服务器
介绍
表述性状态转移(REST)架构是通过API公开来自服务器的数据的最流行方式。
REST 定义了一组必须遵循的原则。有一定的自由度,但客户端必须适应服务器端资源的表示方式,这使得 REST 在某些情况下并不合适。
GraphQL是一种查询语言,它使用强类型系统来提供 API 的详细描述,为开发 API 提供了一种替代模型。
在本教程中,您将学习如何构建一个 GraphQL 服务器,该服务器将公开一个 API 来创建、更新和删除具有以下属性的Book类型的实体:
- ID
- 标题
- 国际标准书号
- 页数
- 作者
作者将是一个具有以下属性的复杂类型:
- ID
- 名
- 姓
您将使用名为 IDL 的特殊 Graphql DSL在 GraphQL 模式中定义这些类型。您还将创建解析器、查询、变异、错误处理程序和服务器的其余基础架构。
本教程将使用:
- Java 9
- 带有嵌入式H2 数据库的Spring Boot 1.5.9
- graphql-java,一个 GraphQL Java 实现
- GraphiQL,一款用于编辑和测试 GraphQL 查询 / 变异的应用程序(您将学习如何使用它的网络版本)
- Maven (但如果你愿意,也可以使用Gradle )
在本教程结束时,您将拥有使用 Spring Boot 通过 GraphQL 构建 API 的坚实基础。
您可以在此GitHub 存储库中找到该项目的完整源代码。
我们先来谈谈 GraphQL。
什么是 GraphQL?
GraphQL 是 Facebook 于 2012 年创建的 API 查询语言,于 2015 年开源,现已作为规范发布。
GraphQL 通过包含以下内容的模式描述 API 提供的数据:
数据类型及其之间的关系
一组操作:
- 查询以获取数据
- 创建、更新和删除数据的变更
例如,以下代码片段定义了Song和Artist类型以及它们的属性和它们之间的关系:
type Song {
id: ID!
title: String!
duration: Int!
genre: String!
artist: Artist!
}
type Artist {
id: ID!
name: String!
country: String!
songs: [Song]
}
请注意,字段是有类型的。这些类型可以是标量类型(Int、Float、String、Boolean和ID)或对规范中定义的其他类型的引用。
您还可以指定它们是否是必需的(!)或者它们是否是数组([])。您可以在这里找到有关对象类型和字段的更多信息。
查询操作也被视为类型。它们声明表示可用操作的字段。例如,您可以定义查询操作来获取所有歌曲并按流派筛选歌曲:
type SongQueries {
allSongs: [Song]
filterSongsByGenre(genre: String!): [Song]
}
schema {
query: SongQueries
}
通过指定返回类型,GraphQL 允许您仅从资源中请求所需的信息。以下是获取所有摇滚歌曲名称的示例查询:
{
filterSongsByGenre(genre: "rock") {
title
}
}
甚至请求相关资源的信息:
{
filterSongsByGenre(genre: "rock") {
title
artist {
name
country
}
}
}
这些查询通常通过 HTTP 发送到单个服务器端点(与 REST 架构不同,其中不同资源有不同的端点)。
响应通常使用 JSON 发送。例如,以下是第一个查询的示例响应:
{
"data": {
"filterSongsByGenre": [
{"title": "Song #0" },
{"title": "Song #1" }
]
}
}
以类似的方式,您可以定义突变来对这些类型执行修改(可以选择定义输入类型):
# ...
input SongInput {
title: String!
genre: String!
duration: Int!
artistID: ID!
}
type SongMutations {
newSong(song: SongInput!): Song
}
schema {
query: SongQueries
mutation: SongMutations
}
以下是基于上述声明的示例突变:
mutation {
newSong(sond: {
title: "Song #2",
duration: 122,
genre: "hrock",
artistID: 1,
}) {
id
title
genre
artist {
name
}
}
}
除了使用突变来修改数据的惯例之外,查询和突变之间的一个重要区别是查询是并行执行的,而突变是一个接一个执行的,以避免竞争条件。
关于 GraphQL还有很多内容需要学习,但这些概念(类型、查询和变异)是基础。
现在我们看看 Spring Boot 如何帮助我们轻松地实现 GraphQL 服务器。
Spring Boot 对 GraphQL 的支持
graphql-java是一个实现 GraphQL 规范的 Java 库。
您可以将库添加为项目的依赖项以开始使用它。在撰写本教程时,最新版本为6.0:
<!-- https://mvnrepository.com/artifact/com.graphql-java/graphql-java -->
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
<version>6.0</version>
</dependency>
但是,您还需要使用GraphQL Java Tools之类的库来解析 GraphQL 模式,而不是以编程方式描述您的类型。此库还会自动将它们映射到 Java 对象:
<!-- https://mvnrepository.com/artifact/com.graphql-java/graphql-java-tools -->
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>4.3.0</version>
</dependency>
如果你正在构建 Web 应用程序,你还需要使用GraphQL Servlet ,它实现了支持GraphQL 查询的GET和POST请求的servlet :
<!-- https://mvnrepository.com/artifact/com.graphql-java/graphql-java-servlet -->
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-servlet</artifactId>
<version>4.7.0</version>
</dependency>
集成所有这些项目需要大量的样板代码。幸运的是,通过使用graphql-spring-boot-starter项目,Spring Boot 支持graphql-java。
您只需将graphql-spring-boot-starter添加到您的项目中:
<!-- https://mvnrepository.com/artifact/com.graphql-java/graphql-spring-boot-starter -->
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>3.10.0</version>
</dependency>
此启动器将在/graphql添加并自动配置一个 GraphQL Servlet ,并使用 GraphQL 模式库(如 GraphQL Java Tools)来解析在类路径上找到的所有模式文件。
此外,以下参数将可用(通过application.yml或application.properties),具有以下默认值:
graphql:
servlet:
mapping: /graphql
enabled: true
corsEnabled: true
然而,在撰写本文时,graphql-spring-boot-starter仅适用于 Spring Boot 1.x,目前不支持 Spring Boot 2。根据此问题,当 Spring Boot 2 的通用版本发布时(目前预计在 2018 年 2 月),将添加对 Spring Boot 2 的支持。
现在让我们使用 Spring Initializr 引导一个 Spring Boot 应用程序。
设置项目
转到<a href="https://translate.google.com/website?sl=en&tl=zh-CN&hl=zh-CN&client=webapp&u=ht
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~