GraphQL是一种查询语言,由Facebook创建,目的是基于直观灵活的语法构建客户端应用程序,用于描述其数据需求和交互。被宣传为Web API的REST替代方案。
传统的REST API使用服务器管理资源的概念,我们可以按照各种HTTP谓词,以一些标准的方式操作这些资源。
当客户端同时需要来自多个资源的数据时,例如请求博客文章和评论时,通常,是通过让客户端发出多个请求或让服务器提供可能并不需要的额外数据来解决。
GraphQL提供的解决方案是:允许客户端准确地指定所需的数据,并允许在单个请求中进行多个数据汇聚查询。比如请求最近的十个帖子的IDL或者SDL:
query {
recentPosts(count: 10, offset: 0) {
id
title
category
author {
id
name
thumbnail
}
}
}
如果使用传统的REST API,可能需要11个请求,1次请求用于获取帖子清单,10个请求用于获取对应帖子的作者信息;或者需要在帖子清单详细信息中包含其作者详细信息。
GraphQL服务器公开了一个描述API的Schemas模式,由类型定义组成,每个类型都有一个或多个字段,每个字段接受零个或更多参数并返回特定类型。
比如GraphQL Schema可能包含以下定义,这些定义描述了帖子、帖子的作者以及获取博客上最新帖子的查询:
type Post {
id: ID!
title: String!
text: String!
category: String
author: Author!
}
type Author {
id: ID!
name: String!
thumbnail: String
posts: [Post]!
}
# The Root Query for the application
type Query {
recentPosts(count: Int, offset: Int): [Post]!
}
# The Root Mutation for the application
type Mutation {
createPost(title: String!, text: String!, category: String, authorId: String!) : Post!
}
某些名称末尾的“!”表示它是一个不可为null的类型。任何没有此项的类型在来自服务器的响应中都可以为null。GraphQL服务正确地处理了这些问题,使我们能够安全地请求可为null类型的子字段。
Spring Boot GraphQL Starter提供了很方便引入GraphQL的方法,使用自动配置和基于注解的编程方法,我们只需要编写服务所需的代码。
org.springframework.boot
spring-boot-starter-graphql
org.springframework.boot
spring-boot-starter-web
因为GraphQL与传输无关,我们需要在配置中包含web相关依赖。通过默认对外端点/graphql,使用SpringMVC通过HTTP公开了GraphQL API。也可以使用其他web实现,例如SpringWebflux。
我们需要将这些“.grapqls”或“.gqls” Schemas模式文件保存在src/main/resources/graphql/**位置下,Spring Boot会自动提取并配置。可以使用spring.graphql.schema.locations自定义位置。
需要使用@QueryMapping注解来标注处理程序方法,并将这些方法放置在@Controller组件中:
@Controller
public class PostController {
private PostDao postDao;
@QueryMapping
public List recentPosts(@Argument int count, @Argument int offset) {
return postDao.getRecentPosts(count, offset);
}
}
定义了recentPosts方法,用来处理Schemas定义的recentPost GraphQL查询。
public class Post {
private String id;
private String title;
private String category;
private String authorId;
}
@SchemaMapping注解将处理程序方法映射到Schemas中具有相同名称的字段,并将其用作该字段的DataFetcher。
@SchemaMapping
public Author author(Post post) {
return authorDao.getAuthor(post.getAuthorId());
}
如果客户端检索Post并且没有请求author字段,那么GraphQL Server不会去执行author()方法,也不会进行DAO调用。
我们也可以在注解中指定父类型名称和字段名称:
@SchemaMapping(typeName="Post", field="author")
public Author getAuthor(Post post) {
return authorDao.getAuthor(post.getAuthorId());
}
与Query类似,通过使用@MutationMapping注解处理程序方法,可以在控制器中定义Mutation:
@MutationMapping
public Post createPost(@Argument String title, @Argument String text,
@Argument String category, @Argument String authorId) {
Post post = new Post();
post.setId(UUID.randomUUID().toString());
post.setTitle(title);
post.setText(text);
post.setCategory(category);
post.setAuthorId(authorId);
postDao.savePost(post);
return post;
}
GraphQL还有一个名为GraphiQL的配套工具。该UI工具可以与任何GraphQL服务器通信,并有助于开发测试GraphQL API。
Spring GraphQL附带了一个默认的GraphQL页面,该页面可以通过/graphiql端点进行访问。默认情况下处于禁用状态,可以通过启用spring.graphql.graphiql.enabled属性。
GraphQL是一项Web服务开发的新技术,可能会彻底改变我们开发Web API的方式。
页面更新:2024-05-19
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号