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
}
}
查詢結果如下:
文檔中我們沒有查詢User類型中的location字段,代碼debug可以驗證,沒有執行location字段的資料擷取方法。
全部字段的查詢:
{
getUserById(id:1) {
id,
name,
location {
id,
name
}
}
}
查詢結果:
整體完成了GraphQL中的文檔定義,字段資料擷取和查詢結果。
使用GraphQL服務,我們可以把提供的資料聚合展示出來,對于各種查詢需求,或者多端展示不同時,自行組合查詢字段完成資料擷取,避免了多個接口的定義。