天天看点

使用Spring GraphQL:字段查询,减少接口(1)

作者:暖杯巧克力aya

1.介绍

GraphQL官网的介绍如下:

GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

一个 GraphQL 服务是通过定义类型和类型上的字段来创建的,然后给每个类型上的每个字段提供解析函数。例如,一个 GraphQL 服务告诉我们当前登录用户是 me,这个用户的名称可能像这样:

type Query {
  me: User
}

type User {
  id: ID
  name: String
}
           

一并的还有每个类型上字段的解析函数:

function Query_me(request) {
  return request.auth.user;
}

function User_name(user) {
  return user.getName();
}
           

一旦一个 GraphQL 服务运行起来(通常在 web 服务的一个 URL 上),它就能接收 GraphQL 查询,并验证和执行。接收到的查询首先会被检查确保它只引用了已定义的类型和字段,然后运行指定的解析函数来生成结果。

例如这个查询:

{
  me {
    name
  }
}
           

会产生这样的JSON结果:

{
  "me": {
    "name": "Luke Skywalker"
  }
}
           

总结来说:GraphQL提供数据的聚合查询。支持哪些数据呢?都列在文档中,下面就是文档信息。

type Query {
  me: User
}

type User {
  id: ID
  name: String
}
           

文档以类型划分字段,字段支持多种类型。比如Query中的me是支持的一个查询字段,它的类型是User。User这种类型中又有id和name两个字段,id是ID类型,name是String类型。

字段的值由GraphQL服务来提供,需要分别定义字段的获取方式。可以从数据库查询或者程序计算或从其他存储形式获取。GraphQL文档中可以定义很多字段,单个业务查询只需要其中几个时,查询文档就声明需要的字段,GraphQL只会发起声明字段的查询。

2.使用

2.1 声明文档,列出支持的查询字段。Query是查询的入口,那么我们可以查询getUserById,返回值类型是User,参数是id。返回值User类型,包含id,name和location字段。

type Query {
  getUserById(id: ID): User
}

type User {
  id: ID
  name: String
  location: Location
}

type Location {
	id: ID
	name: String
}
           

2.2 定义字段的数据获取。需要将数据获取的方法放在带有@Controller注解的Controller类中。数据获取的方法需要使用注解@QueryMapping,参数使用@Argument注解,注解@BatchMapping暂时理解成批量获取子字段。

@Controller
public class UserController {
    @QueryMapping
    public User getUserById(@Argument Integer id) {
				//此处的查询参数,id并没有使用,只列举该功能
        User user = new User();
        user.setName("aaa");
        user.setId(1);
        return user;
    }

    @BatchMapping(field = "location", typeName = "User")
    public Map<User, Location> getLocation(@Argument List<User> users) {
        Location location = new Location();
        location.setId(11);
        location.setName("location11");
        return Map.of(users.get(0), location);
    }
}
           

2.3 查询数据。运行GraphQL服务程序,使用graphigl界面访问工具或者访问接口${服务地址}/graphql。

设置查询文档:

{
  getUserById(id:1) {
    id,
    name
  }
}
           

查询结果如下:

使用Spring GraphQL:字段查询,减少接口(1)

文档中我们没有查询User类型中的location字段,代码debug可以验证,没有执行location字段的数据获取方法。

全部字段的查询:

{
  getUserById(id:1) {
    id,
    name,
    location {
      id,
      name
    }
  }
}
           

查询结果:

使用Spring GraphQL:字段查询,减少接口(1)

整体完成了GraphQL中的文档定义,字段数据获取和查询结果。

使用GraphQL服务,我们可以把提供的数据聚合展示出来,对于各种查询需求,或者多端展示不同时,自行组合查询字段完成数据获取,避免了多个接口的定义。