hello,大家好,我是小黑,又和大家見面啦~
新開一個專題是關于 GraphQL 的相關內容,主要是通過 Spring Boot 來快速開發 GraphQL 應用,希望對剛接觸 GraphQL 的同學有所幫助,
專案 github 地址:https://github.com/shenjianeng/graphql-spring-boot-example
什么是 GraphQL
先看一下官網的解釋:
https://graphql.org/
GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.
https://graphql.cn/
GraphQL 既是一種用于 API 的查詢語言也是一個滿足你資料查詢的運行時, GraphQL 對你的 API 中的資料提供了一套易于理解的完整描述,使得客戶端能夠準確地獲得它需要的資料,而且沒有任何冗余,也讓 API 更容易地隨著時間推移而演進,還能用于構建強大的開發者工具,
再看一下維基百科的解釋:
https://en.wikipedia.org/wiki/GraphQL
GraphQL is an open-source data query and manipulation language for APIs, and a runtime for fulfilling queries with existing data.GraphQL was developed internally by Facebook in 2012 before being publicly released in 2015.
It allows clients to define the structure of the data required, and the same structure of the data is returned from the server.
GraphQL 是一種用于 api 的開源資料查詢和操作語言,也是一種用于實作現有資料查詢的運行時,GraphQL 于2012年由 Facebook內部開發,2015年公開發布,
它允許客戶端定義所需資料的結構,并從服務器回傳相同的資料結構,
從字面上理解:GraphQL = Graph + QL = 圖表化、可視化的查詢語言,它允許客戶端定義所需資料的結構,并從服務器回傳相同的資料結構,
Hello world
GraphQL 是一種規范,已有多種編程語言支持,
在本系列文章中,我們使用 graphql-spring-boot-starter 來完成 GraphQL 相關開發講解,
github 地址:https://github.com/graphql-java-kickstart/graphql-spring-boot
引入相關依賴
構建一個基礎的 Spring Boot Web 專案工程,引入最新的 graphql-spring-boot-starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>8.0.0</version>
</dependency>
通過 maven 我們可以很清楚的看到 graphql-spring-boot-starter 引入了哪些依賴包:

graphql-spring-boot-starter 默認情況下會掃描 classpath 下所有的 graphqls 后綴檔案,
當然,我們也可以通過 application.properties 來配置修改相關屬性,本案例中,我們使用默認配置即可,

撰寫第一個 graphqls 檔案
在 resources 檔案夾下新建 schema.graphqls 檔案,
如果你在使用 idea 的話,可以安裝 https://plugins.jetbrains.com/plugin/8097-js-graphql 插件來幫助你撰寫 graphqls 檔案,
# 表示構建一個 user 資料結構
type User{
# id,型別就是 ID ,! 表示是必填欄位
id:ID!
# username 欄位,String 型別
username:String!
nickname:String!
# city 欄位,型別是 City 列舉
city:City
}
# City 列舉值
enum City{
hangzhou
shanghai
}
# 查詢相關介面
type Query{
# 獲取用戶串列,回傳 user 陣列
userList:[User!]
}
上述 schema.graphqls 檔案中定義了 User 和 City 這兩種資料型別,同時,我們生成兩個 Java Bean 來與之相對應,
public enum City {
hangzhou,
shanghai,
}
@Data
public class User {
private UUID id;
private String username;
private String nickname;
private City city;
}
定義 GraphQLQueryResolver
@Component
public class UserGraphQLQueryResolver implements GraphQLQueryResolver {
public Collection<User> userList() {
User user1 = new User();
user1.setId(UUID.randomUUID());
user1.setUsername("coder小黑");
user1.setNickname("coder小黑沒有昵稱");
user1.setCity(City.hangzhou);
User user2 = new User();
user2.setId(UUID.randomUUID());
user2.setUsername("今晚打老虎");
user2.setNickname("愛老虎油");
user2.setCity(City.shanghai);
return Arrays.asList(user1, user2);
}
}
- 定義了一個 Spring Beran
UserGraphQLQueryResolver,實作了graphql.kickstart.tools.GraphQLQueryResolver介面 - 有一個名為
userList的方法,方法不需要入參,回傳Collection<User>
沒錯,聰明的讀者同學是不是已經發現了:
UserGraphQLQueryResolver#userList 就是用來匹配 schema.graphqls 檔案中定義的獲取用戶串列查詢,

使用 graphiql 請求服務器
graphiql 可以幫助我們方便的向 graphql 服務端發起請求,使用也十分簡單,引入相關依賴即可,
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphiql-spring-boot-starter</artifactId>
<version>8.0.0</version>
<scope>runtime</scope>
</dependency>
好,讓我們啟動 Spring Boot 應用,訪問 http://localhost:8080/graphiql

在 https://github.com/graphql-java-kickstart/graphql-spring-boot 的幫助下,實作一個 graphql 服務就是這么的簡單,
自定義 Servlet Mapping 地址
我們來看看客戶端發出的請求長什么樣子:

同時,我們可以通過 application.properties 檔案來修改服務端的請求接收路徑:
graphql.servlet.mapping=/coder-xiao-hei
使用原生 GraphQL 實作
下面,我們再使用 GraphQL 的原生 api 來實作一下上述的案例,
public class HelloWorld {
static Collection<User> userList() {
User user1 = new User();
user1.setId(UUID.randomUUID());
user1.setUsername("coder小黑");
user1.setNickname("coder小黑沒有昵稱");
user1.setCity(City.hangzhou);
return Collections.singletonList(user1);
}
public static void main(String[] args) throws IOException {
Resource resource = new DefaultResourceLoader().getResource("classpath:schema.graphqls");
String schema = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
SchemaParser schemaParser = new SchemaParser();
TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema);
RuntimeWiring runtimeWiring =
RuntimeWiring.newRuntimeWiring()
.type(TypeRuntimeWiring
.newTypeWiring("Query")
.dataFetcher("userList",
(DataFetcher<Collection<User>>) environment -> userList()))
.build();
SchemaGenerator schemaGenerator = new SchemaGenerator();
GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);
GraphQL build = GraphQL.newGraphQL(graphQLSchema).build();
ExecutionResult executionResult = build.execute("query{\n" +
" userList{\n" +
" id\n" +
" username\n" +
" }\n" +
"}");
// {userList=[{id=486a181e-eec7-4001-a9d9-65e94a004f8c, username=coder小黑}]}
System.out.println(executionResult.getData().toString());
}
}
下圖清晰的描述了上述程式中相關組件的關系:

下期預告
下期我們將使用 graphQL 來實作簡單的增刪改查和自定義標量型別,感謝大家的關注和閱讀~~
參考資料:
https://github.com/graphql-java-kickstart/graphql-spring-boot
https://graphql.org
https://www.graphql-java.com/tutorials/getting-started-with-spring-boot/
https://graphql.org/code/#java-kotlin
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/238315.html
標籤:Java
上一篇:記一次死鎖分析程序
