当前端应用跨多端时,常碰到的问题有:
为了解决这些问题GraphQL应运而生,其对应的能力为:
有了以上能力,前端就可以根据已有的后端服务和实际业务要求灵活定制查询请求,不用再去麻烦后端哥哥开发新的服务了。
<!-- https://mvnrepository.com/artifact/com.graphql-java/graphql-spring-boot-starter --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-spring-boot-starter</artifactId> <version>5.0.2</version> </dependency> <!-- https://mvnrepository.com/artifact/com.graphql-java/graphql-java-tools --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java-tools</artifactId> <version>5.2.4</version> </dependency> <!-- https://mvnrepository.com/artifact/com.graphql-java/graphiql-spring-boot-starter --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphiql-spring-boot-starter</artifactId> <version>5.0.2</version> </dependency> 复制代码
查询服务
需要支持GraphQL的查询服务要实现GraphQLQueryResolver接口,该接口仅仅是一个声明接口,没有任何方法。参考代码如下:
@Component public class BookQueryResolver implements GraphQLQueryResolver { public List<Book> findBooks() { Author author = new Author(1, "Lee", 30); Book book = new Book(1, "Java 8实战", author, "电子工业出版社"); List<Book> bookList = new ArrayList<Book>(); bookList.add(book); return bookList; } public Book findBook(Integer id) { if (id == 1) { Author author = new Author(1, "Lee", 30); Book book = new Book(1, "Java 8实战", author, "电子工业出版社"); return book; } else { return null; } } public Dog findDog(String name) { if (null != name && name.equals("xiaofei")) { return new Dog("xiaofei", 3, "male"); } else { return null; } } } 复制代码
可以看到类上需要添加@Component注解。
配置GraphQL的schema
schema配置文件可以放到resources目录下,为了支持查询有两类配置:
1)数据对象配置,这些数据对象和查询服务返回的对象对应,字段可以比实际返回对象少,没有定义的则不返回。
type Author { id: Int name: String age: Int } type Book { id: Int name: String author: Author publisher: String } type Dog { name: String age: Int gender: String } 复制代码
type Query { findBooks: [Book] findBook(id:Int):Book findDog(name: String!):Dog findDogByName(name: String!):Dog } 复制代码
以上完成之后就可以使用查询服务了。
GraphQL自带了一个测试工具,浏览器中输入: http://localhost:7000/graphiql 打开测试工具界面。(注:端口号为spring端口号,请自行修改)。
左边是查询请求,右边是返回结果,可以看到在查询请求中:
完美实现了之前我们提到的两点要求。
在引入GraphQL之前,spring中前端和后端的接口通过Controller连接,如果Controller能被复用,不需要再重新写QueryResolver那不是完美了,实践证明,两者可以共存,只要Controller类实现GraphQLQueryResolver接口则可,这样既可以支持以前的Rest接口查询,又可以支持GraphQL查询。参考代码如下:
@RestController public class QueryController implements GraphQLQueryResolver { @RequestMapping("/findDogByName") public Dog findDogByName(@RequestBody String name) throws Exception { if (null != name && name.equals("xiaofei")) { return new Dog("xiaofei", 3, "male"); } else { return null; } } } 复制代码
end.
完整实例代码扫码加入微信公众号并回复:webfullstack,获取仓库地址。