前言
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 title\n releaseYear\n }\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"); } }