graphql--快速了解graphql特点

graphql--快速了解graphql特点

今天浏览博客时看到graphQL,之前在招聘网站上第一次接触,以为是图数据查询语言,

简单了解后,发现对graphQL的介绍主要是用作API的查询语言,不仅限于图数据查询

如图:自定义返回的数据体字段(接口调用工具是graphql-starter自带的)


1.它的作用

graphQL是一种API查询语言,什么是API查询语言呢?并不是指用来查询API的,而是用来查询API提供的数据,一种为API而生的查询语言。

它通过提供一种灵活、精确的查询方式,解决了传统RESTful API的一些局限性,使得客户端能够更加高效地获取所需的数据。

那么现有风格的API有哪些问题呢?以下两点是我个人比较认可的:

  • 返回的数据结构是固定的。要么字段多了,要么字段少了。这种情况应该都经历过,字段多了,虽然调用者可以自行挑选需要的字段,但数据结构庞杂且占用带宽,字段少了
    则需要调整后端接口。
  • 接口数量太多。操作一个数据实体,CRUD没跑了。也正因为接口太多,才会有各种接口管理规范和工具的出现,比如swagger、apifox等。

那么上述问题,在graphQL中被解决:

  • 接口返回的数据字段由调用方自行决定。客户端可以根据schema自行决定查询哪些字段属性,不存在过多或不足。
  • 单一端点,对,没有错,一个系统只有一个接口。只要你想,你可以将员工、保险、立项这些风马牛不相及的对象都杂糅在一起 (当然,按照我们工程化、模块化的管理思路,以及高内聚的思想,还是按照领域进行划分,也便于维护管理)

上述这两条已经让人眼前一亮了,不是吗?至于有些资料提到的graphQL相较于RESTful API的优势,比如复杂数据需要多次查询,接口版本演进等,

我个人觉得这些并不是RESTful 的问题,而是在于接口设计的问题。接口设计如果有问题,再好的工具也会疲软。

2.demo示例

光说不太直观,通过demo感受一些graphQL的魅力(之前没注意到,spring官网居然也给出了GraphQL对应的入门demo)

2.1依赖引入

xml 复制代码
<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>

2.2定义schema

既然是单一端点,那么除了查询,还可以定义保存和删除

graphql 复制代码
# @author: yuanye.wang
# 定义操作:查询
type Query{
    # 通过ID查询
    getById(id: ID): Book
    # 通过name查询
    #bookByName(name: String!) :[Book]
}

# 定义操作:保存、删除等(对应graphql中的变异 mutation)
type Mutation{
    createBook(name: String, pageCount: Int!, authorFirstName: String, authorLastName:String): Book
    #updateBook(id: ID, name: String!, pageCount: Int!): Book
    #deleteBook(id:ID): String
}

# 自定义数据类型(内置类型以外的数据)
type Author {
    id: ID
    firstName: String
    lastName: String
}
type Book {
    id: ID
    name: String
    pageCount: Int
    author: Author
}

2.3定义GrapQL端点

springboot提供了对应的starter,直接上注解。可以认为通过这些注解,将会在/graphql端点中暴露对应的方法(不再是直接将controller方法暴露为端点)

java 复制代码
@RestController
public class BookController {
    @Autowired
    BookService bookService;

    // @SchemaMapping(typeName = "Query", value = "getById")
    @QueryMapping(value = "getById")
    public Book getById2(@Argument String id) {
        return bookService.getById(id);
    }

    @MutationMapping(value = "createBook")
    public Book createBook(@Argument String name,
                           @Argument int pageCount,
                           @Argument String authorFirstName,
                           @Argument String authorLastName) {
        return bookService.createBook(name,pageCount,authorFirstName,authorLastName);
    }
}

2.4运行测试

IDEA 、apifox中都可以执行,也可以开启graphql内置的浏览器工具: spring.graphql.graphiql.enabled=true ,以IDEA http举例。

我们在/graphql端点中暴露了两个方法:

  1. getById
  2. createBook
shell 复制代码
### 自定义查询
GRAPHQL http://localhost:8081/graphql
# 1.声明要调用的方法
query  getById($id: ID) {
  getById(id: $id) {
      # 2.自定义返回对象的字段
      id
      name
      pageCount
      author {
          id
          firstName
          lastName
      }
  }
}
# 3.传入实参
{
   "id": "1"
}

### 新增,和查询同一个端口
GRAPHQL http://localhost:8081/graphql

mutation  createBook($name: String, $pageCount: Int!, $authorFirstName: String, $authorLastName: String) {
  createBook(name: $name, pageCount: $pageCount, authorFirstName: $authorFirstName, authorLastName: $authorLastName) {
      id
      name
      pageCount
      author {
          id
          firstName
          lastName
      }
  }
}

{
   "name": "demo",
   "pageCount": "666",
   "authorFirstName": "fname",
   "authorLastName": "lname"
}

2.5一些坑

  1. IDEA中GraphQL插件创建的文件是xxx.graphql,导致项目启动失败,需要改为 xxx.graphqls(spring官网demo有提到,没留意这个s,花了很长时间解决)
  2. 请求端口是/graphql, 浏览器UI工具是 /graphiql
相关推荐
炒空心菜菜11 分钟前
MapReduce 实现 WordCount
java·开发语言·ide·后端·spark·eclipse·mapreduce
wowocpp2 小时前
spring boot Controller 和 RestController 的区别
java·spring boot·后端
后青春期的诗go2 小时前
基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(二)
开发语言·后端·rust·rocket框架
freellf3 小时前
go语言学习进阶
后端·学习·golang
全栈派森5 小时前
云存储最佳实践
后端·python·程序人生·flask
CircleMouse5 小时前
基于 RedisTemplate 的分页缓存设计
java·开发语言·后端·spring·缓存
獨枭6 小时前
使用 163 邮箱实现 Spring Boot 邮箱验证码登录
java·spring boot·后端
维基框架6 小时前
Spring Boot 封装 MinIO 工具
java·spring boot·后端
秋野酱6 小时前
基于javaweb的SpringBoot酒店管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
☞无能盖世♛逞何英雄☜6 小时前
Flask框架搭建
后端·python·flask