GraphQL是什么?
GraphQl官方的定义是:
GraphQL是一种API的查询语言。 它用于运行时完成数据查询。 GraphQL服务与传输无关,但通常通过HTTP提供。
GraphQl特性
- GraphQL query, 只请求需要的数据
- GraphQL schema, 在服务器端定义了api的数据结构
- 可以在一个请求中获取多个数据,如果是rest的话, 需要访问多个接口
与REST对比,REST的缺点的主要有以下:
- Overfetching 往往会给客户端返回过多的数据
- endpoints过多,管理endpoints是个问题。Endpoints修改,客户端也需要修改。
GraphQL只是一种协议, 官方提供了多种实现。如java, javascript.
GraphQL中的类型
-
scalar type
GraphQL的Scalar Type有Int, String, Float, Boolean, ID
-
object type
-
Fragments
fragment liftInfo on Lift { name status capacity night elevationGain }
query { Lift(id: "jazz-cat") { ...liftInfo trailAccess { name difficulty } } Trail(id: "river-run") { name difficulty accessedByLifts { ...liftInfo } } }
The fragment in this example is named
liftInfo
, and it is a selection set on theLift
type. -
union type
union AgendaItem = StudyGroup | Workout type StudyGroup { name: String! subject: String students: [User!]! } type Workout { name: String! reps: Int! } type Query { agenda: [AgendaItem!]! }
-
interface
Interfaces are another option when dealing with multiple object types that could be returned by a single field. An interface is an abstract type that establishes a list of fields that should be implemented in similar object types. When another type implements the interface, it includes all of the fields from the interface and usually some of its own fields.
interface AgendaItem { name: String! start: DateTime! end: DateTime! } type StudyGroup implements AgendaItem { name: String! start: DateTime! end: DateTime! participants: [User!]! topic: String! } type Workout implements AgendaItem { name: String! start: DateTime! end: DateTime! reps: Int! } type Query { agenda: [AgendaItem!]! }
-
enums
enum PhotoCategory { SELFIE PORTRAIT ACTION LANDSCAPE GRAPHIC }
type Photo { id: ID! name: String! url: String! description: String created: DateTime! category: PhotoCategory! }
GraphQL的Java使用
源码地址:https://github.com/caijh/samples/tree/master/sample-graphql
-
引入maven依赖
<dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java</artifactId> <version>11.0</version> </dependency> <dependency> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-spring-boot-starter</artifactId> <version>5.0.2</version> </dependency> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java-tools</artifactId> <version>5.2.4</version> </dependency> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphiql-spring-boot-starter</artifactId> <version>5.0.2</version> </dependency>
-
建立表
create table `author` ( id bigint primary key auto_increment, name varchar(45) not null, birthday datetime default null ) engine = InnoDB default charset=utf8 comment '作者'; create table `article` ( id bigint primary key auto_increment, title varchar(100) not null, author_id bigint not null, content text not null ) engine = InnoDB default charset = utf8 comment '文章';
-
创建graphqls
schema.graphql
scalar Date type Query { } type Mutation { }
author.graphqls
extend type Query { findAuthorById(id: Int): Author } extend type Mutation { newAuthor(name: String, birthday: Date): Boolean } type Author { id: ID name: String birthday: Date }
article.graphqls
extend type Query { findArticleById(id: Int) : Article } extend type Mutation { newArticle(title: String, content: String, authorId: Int): Boolean } type Article { id: ID title: String content: String authorId: Int }
-
创建Query和Mutation
package com.coding.sample.graphql.component; import com.coding.sample.graphql.entity.Article; import com.coding.sample.graphql.entity.Author; import com.coding.sample.graphql.mapper.ArticleMapper; import com.coding.sample.graphql.mapper.AuthorMapper; import com.coxautodev.graphql.tools.GraphQLQueryResolver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Query implements GraphQLQueryResolver { @Autowired private AuthorMapper authorMapper; @Autowired private ArticleMapper articleMapper; public Author findAuthorById(Long id) { return authorMapper.selectByPrimaryKey(id); } public Article findArticleById(Long id) { return articleMapper.selectByPrimaryKey(id); } }
package com.coding.sample.graphql.component; import java.util.Date; import com.coding.sample.graphql.entity.Article; import com.coding.sample.graphql.entity.Author; import com.coding.sample.graphql.mapper.ArticleMapper; import com.coding.sample.graphql.mapper.AuthorMapper; import com.coxautodev.graphql.tools.GraphQLMutationResolver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Mutation implements GraphQLMutationResolver { @Autowired private AuthorMapper authorMapper; @Autowired private ArticleMapper articleMapper; public boolean newAuthor(String name, Date birthday) { Author author = new Author(); author.setName(name); author.setBirthday(birthday); return authorMapper.insert(author) > 0; } public boolean newArticle(String title, String content, Long authorId) { Article article = new Article(); article.setTitle(title); article.setContent(content); article.setAuthorId(authorId); articleMapper.insert(article); return true; } }
-
测试