GraphQL 是一個用于 API 的查詢語言,是一個使用基于類型系統來執行查詢的服務端運行時(類型系統由你的數據定義)。GraphQL 并沒有和任何特定數據庫或者存儲引擎綁定,而是依靠你現有的代碼和數據支撐。
可見 GraphQL 的作用類似傳統的 Web API 接口(比如 RESTful API),都是提供了一種數據訪問的形式,但是在一些場景下有著更好的使用體驗,比如:
如果使用 RESTful API 客戶端只能固定接收接口設計時返回字段的數據;而 GraphQL 中,客戶端可以按需指定要接收哪些字段的數據。所以,面對一些復雜的數據查詢可能需要多個 RESTful API 接口,如果使用 GraphQL 只需要一個查詢接口就可以實現,因為客戶端可以按需接收數據,更加的靈活方便。當然 GraphQL 不只查詢,一些修改相關的功能也是沒問題的。
準備工作
首先添加 GraphQL 相關的依賴,這里使用 GraphiQL 作為前端圖形化工具來訪問 graphql 接口:
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>11.1.0</version>
</dependency>
<!-- 訪問 graphql 接口的圖形化工具 -->
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphiql-spring-boot-starter</artifactId>
<version>11.1.0</version>
</dependency>
然后就是graphql
、graphiql
的相關配置了:
server:
port: 8848
graphql:
servlet:
enabled: true
mapping: /graphql
exception-handlers-enabled: true
context-setting: PER_REQUEST_WITH_INSTRUMENTATION
tools:
schema-location-pattern: /graphql/schema.graphqls
graphiql:
mapping: /graphiql
endpoint:
graphql: /graphql
enabled: true
basePath: /
pageTitle: GraphiQL
props:
resources:
query: /graphql/schema.graphqls
variables:
editorTheme: "solarized light"
編寫 graphqls 文件
上邊application.yml
配置文件里引用了一個schema.graphqls
文件,里邊定義了 graphql 查詢、變更相關的接口,以及返回的對象類型、輸入的對象類型等。
type Query {
user(name: String!, age: Int!): User
users(input: UserInput): [User]
}
type Mutation {
addUser(input: UserInput!): Result
}
type User {
id: String!
name: String!
age: Int
}
type Result {
code: Int!
msg: String!
}
input UserInput {
name: String!
age: Int
}
-
Query
:查詢類型,里邊定義了查詢操作相關的接口 -
Mutation
:變更類型,里邊定義了變更操作相關的接口 -
User
、Result
是普通的自定義對象類型,這里用作接口返回值 -
UserInput
是一個可以作為接口參數的輸入對象類型,User
、Result
卻不可以 -
String
、Int
則是基礎類型,基礎類型可以直接作為接口參數 -
name: String!
表示字段值不為空 -
[User]
表示數組
這里先簡單的了解下 GraphQL 的用法,更多的內容可參考官方文檔 https://graphql.cn/learn/
對象類型類
在schema.graphqls
中定義了User
、Result
、UserInput
三個對象類型,還需要給它們定義對應的 Java 類:
// Result .java
@Data
@AllArgsConstructor
public class Result {
private Integer code;
private String msg;
}
// User .java
@Data
@AllArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
}
// UserInput.java
@Data
public class UserInput {
private String name;
private Integer age;
}
這里用lombok
來簡化代碼!
解析器
前邊已經定義好了查詢、變更操作的接口,還需要定義對應的解析器來實現對應的接口方法。
實現查詢相關的接口需要用到GraphQLQueryResolver
:
@Component
public class QueryResolver implements GraphQLQueryResolver {
public User user(String name, Integer age) {
return new User(1L, name, age);
}
public List<User> users(UserInput input) {
List<User> users = new ArrayList<>();
users.add(new User(1L, "aaa", 10));
users.add(new User(2L, "bbb", 11));
return users;
}
}
實現變更相關的接口需要用到GraphQLMutationResolver
:
@Slf4j
@Component
public class MutationResolver implements GraphQLMutationResolver {
public Result addUser(UserInput input) {
log.info(input.toString());
return new Result(200, "success");
}
}
這里簡單起見直接在內存中創建了一些數據,實際中可以結合各種數據數據存儲層技術。
測試
啟動項目后,用瀏覽器訪問 http://localhost:8848/graphiql 就可以使用 GraphiQL 來進行測試了: