环境:Springboot3.0.9
概述
- 一种用于 API 的查询语言
GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。
- 请求你所要的数据
向你的 API 发出一个 GraphQL 请求就能准确获得你想要的数据,不多不少。 GraphQL 查询总是返回可预测的结果。使用 GraphQL 的应用可以工作得又快又稳,因为控制数据的是应用,而不是服务器。
- 获取多个资源
GraphQL 查询不仅能够获得资源的属性,还能沿着资源间引用进一步查询。典型的 REST API 请求多个资源时得载入多个 URL,而 GraphQL 可以通过一次请求就获取你应用所需的所有数据。这样一来,即使是比较慢的移动网络连接下,使用 GraphQL 的应用也能表现得足够迅速。
- 描述所有的可能
GraphQL API 基于类型和字段的方式进行组织,而非入口端点。你可以通过一个单一入口端点得到你所有的数据能力。GraphQL 使用类型来保证应用只请求可能的数据,还提供了清晰的辅助性错误信息。应用可以使用类型,而避免编写手动解析代码。
有关GraphQL的语法相关知识,请参考
中文
接下来将以一个完整的示例演示GraphQL的使用。
环境配置
-
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-graphql</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> -
配置文件
spring:
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/testjpa?serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&useSSL=false
username: root
password: xxxxxx
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimumIdle: 10
maximumPoolSize: 200
autoCommit: true
idleTimeout: 30000
poolName: MasterDatabookHikariCP
maxLifetime: 1800000
connectionTimeout: 30000
connectionTestQuery: SELECT 1spring:
jpa:
generateDdl: false
hibernate:
ddlAuto: update
openInView: true
show-sql: truespring:
graphql:
path: /graphql
graphiql:
enabled: true
path: /graphiql
cors:
allow-credentials: true
allowed-headers: ''
allowed-methods: ''
schema:
locations:
- classpath*:graphql/**/
file-extensions:
- .graphqls
- .gqls
printer:
enabled: true
注意:这里的
spring.graphql.graphql.enabled=true开启后,将会提供一个UI界面供我们快速查询测试使用
做好以上配置后,接下来就是建立2张表t_book和t_author。
实体定义
Book
@Entity
@Table(name = "t_book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id ;
private String name ;
private Integer pageCount ;
@Transient
private List<Author> author = new ArrayList<>();
}
Author
@Entity
@Table(name = "t_author")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id ;
private String firstName ;
private String lastName ;
// Book表的主键
private Long bid ;
}
Repository定义
BookRepository
public interface BookRepository extends JpaRepository<Book, Long>, JpaSpecificationExecutor<Book> {
}
AuthorRepository
public interface AuthorRepository extends JpaRepository<Author, Long>, JpaSpecificationExecutor<Author> {
List<Author> findByBid(Long bid) ;
}
Service定义
@Service
public class BookService {
@Resource
private BookRepository bookRepository ;
@Resource
private AuthorRepository authorRepository ;
public Book queryBook(Long id) {
Book book = bookRepository.findById(id).orElse(null) ;
List<Author> authors = authorRepository.findByBid(id) ;
book.setAuthor(authors) ;
return book ;
}
}
以上是基本的数据库操作,很容易理解。接下来就是定义GraphQL Schema
GraphQL Schema定义
schema {
query: BookQuery
}
type BookQuery {
bookById(id: ID): Book
}
type Book {
id: ID
name: String
pageCount: Int
author: [Author]
}
type Author {
id: ID
firstName: String
lastName: String
}
有关graphql相关语法请参考上面提到的网址。接下来是定义访问接口
Controller接口
@Controller
public class BookController {
@Resource
private BookService bookService;
@Resource
private AuthorRepository authorRepository;
@SchemaMapping(typeName = "BookQuery", field = "bookById")
public Book bookById(@Argument Long id) {
return bookService.queryBook(id);
}
}
访问测试
只需访问统一的入口即可:
#该访问路径可以在配置文件中修改
这里是访问的完整的信息,我们可以在请求的query中设置需要访问的字段,如下:
只访问book信息
只访问部分字段信息
你需要访问那些字段,是完全由客户端定义的。