天天看點

使用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服務,我們可以把提供的資料聚合展示出來,對于各種查詢需求,或者多端展示不同時,自行組合查詢字段完成資料擷取,避免了多個接口的定義。