GraphQL 既是一種用於 API 的查詢語言也是一個滿足你數據查詢的運行時。 GraphQL 對你的 API 中的數據提供了一套易於理解的完整描述,使得客戶端能夠准確地獲得它需要的數據,而且沒有任何冗余,也讓 API 更容易地隨着時間推移而演進,還能用於構建強大的開發者工具。
基於node的服務端開發中,GraphQL技術較為成熟常用,在基於java的服務端開發中,由於國內對該API標准的了解程度不高,以及引入GraphQL可能需要維護兩份重復數據(schema和相應java代碼實現)。目前在Java服務端開發領域,Graphql Java的應用還較為有限。
本文旨在從Java服務端開發的角度,介紹GraphQL的落地實踐。由官方文檔開始,循序漸進的介紹引入GraphQL對服務端開發帶來的好處,以及基於GraphQL Java框架的注解式聲明方式,逐步優化GraphQL的引入流程。
一、開始
graphql-java至少需要在java8平台上運行。
1.1 在gradle中使用
保證mavenCentral在repo當中
repositories {
mavenCentral()
}
添加依賴如下:
dependencies {
compile 'com.graphql-java:graphql-java:13.0'
}
1.2 在Maven中使用
依賴如下:
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
<version>113.0</version>
</dependency>
二、Hello World示例
示例代碼如下:
import graphql.ExecutionResult;
import graphql.GraphQL;
import graphql.schema.GraphQLSchema;
import graphql.schema.StaticDataFetcher;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;
import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring;
public class HelloWorld {
public static void main(String[] args) {
String schema = "type Query{hello: String}";
SchemaParser schemaParser = new SchemaParser();
TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema);
RuntimeWiring runtimeWiring = newRuntimeWiring()
.type("Query", builder -> builder.dataFetcher("hello", new StaticDataFetcher("world")))
.build();
SchemaGenerator schemaGenerator = new SchemaGenerator();
GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);
GraphQL build = GraphQL.newGraphQL(graphQLSchema).build();
ExecutionResult executionResult = build.execute("{hello}");
System.out.println(executionResult.getData().toString());
// Prints: {hello=world}
}
}
示例中展示了一個最簡單的hello world示例,主要包含如下幾個部分:
2.1 Schema
Schema,可理解為GraphQL的概要,描述了相關的類型信息、可執行的操作等。
在本例中,我們定義了一個Schema如下:
type Query{hello: String}
其中,Query類型的操作,只包含一個hello字段,並且返回String類型數據。
2.2 TypeDefinitionRegistry
類型定義。在Java代碼中,通過加載Schema文件或描述,將其解析為TypeDefinitionRegistry。
2.3 RuntimeWiring
運行時織入。僅有Schema及其類型定義還不夠,在Java中要實際運行GraphQL`,還需要顯式指定定義中的每個操作,該觸發什么樣的行為。
例如,在本例中,builder -> builder.dataFetcher("hello", new StaticDataFetcher("world")
表示當查詢Query類型下的hello字段時,返回值為"world"。
2.4 GraphQL
在結合前面TypeDefinitionRegistry和RuntimeWiring的基礎上,生成的可運行的GraphQL實例。
2.5 ExecutionResult
每次執行GraphQL操作時,返回的結果對象。其中包含error字段,用於保存執行過程中的報錯信息。data字段,用於獲取執行結果返回值。