前言
Netflix 已開放其 Domain Graph Service(DGS)框架的源代碼 ,該框架是為了方便整合 GraphQL 使用,用于簡化 GraphQL 的實現。
GraphQL 主要是作用于數據接口,比如前端后端交互。無需定義或修改后臺 Controller、Service 等業務代碼即可實現靈活的數據變更,客戶端可以自由獲取服務端事先定義好的數據,提高了交互接口的靈活性
組件依賴
graphql-dgs-spring-boot-starter
<dependency>
<groupId>com.netflix.graphql.dgs</groupId>
<artifactId>graphql-dgs-spring-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
DGS 必須從 jcenter 下載,不然部分依賴者無法下載。踩坑很久
<profiles>
<profile>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>bintray</name>
<url>https://jcenter.bintray.com</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>bintray-plugins</name>
<url>https://jcenter.bintray.com</url>
</pluginRepository>
</pluginRepositories>
<id>bintray</id>
</profile>
</profiles>
定義接口 schema
/src/main/resources/schema/schema.graphqls
此文件定義了客戶端請求入參格式和查詢數據類型
type Query {
shows(title: String ,releaseYear: Int): [Show]
}
type Show {
title: String
releaseYear: Int
}
定義數據抽取規則
@DgsComponent
public class ShowsDatafetcher {
@DgsData(parentType = "Query", field = "shows")
public List<Show> shows(@InputArgument("title") String title, @InputArgument("releaseYear") Integer releaseYear) {
if (title == null) {
return shows;
}
return shows.stream().filter(s -> s.getTitle().contains(title)).collect(Collectors.toList());
}
// 模擬 DB 查詢
private final List<Show> shows = List.of(
new Show("JAVA", 1995),
new Show("php", 1995),
new Show("Python", 1990),
new Show("golang", 2009),
new Show("rust", 2015)
);
}
UI 前端調試
訪問:
http://localhost:8080/graphiql
條件查詢
接口調用
curl --location --request POST 'http://localhost:8080/graphql'
--header 'Content-Type: Application/json'
--data-raw '{"query":"{n shows(title: "java", releaseYear: 1995) {n titlen releaseYearn }n}n","variables":null}'
java 調用
@SpringBootTest(classes = {DgsAutoConfiguration.class, ShowsDatafetcher.class})
class ShowsDatafetcherTests {
@Autowired
DgsQueryExecutor dgsQueryExecutor;
@Test
void shows() {
List<String> titles = dgsQueryExecutor.executeAndExtractJsonPath(
" { shows { title releaseYear }}",
"data.shows[*].title");
assertThat(titles).contains("java");
}
}