Web应用全栈之旅-Spring篇(四)集成GraphQL

1、背景

当前端应用跨多端时,常碰到的问题有:前端

  1. 各端须要获取的信息量不一样,例如手机端因为显示屏的大小须要获取的数据比PC端少,若是和PC端共用相同的接口,那么返回了不少冗余的数据,影响性能。
  2. 各端对数据的要求不一样,有时须要聚合多个后端服务的数据,每个聚合场景都新增一个服务会致使前端和后端耦合太紧;若是分屡次调用又增长了先后端交互次数,从而影响性能。

为了解决这些问题GraphQL应运而生,其对应的能力为:java

  1. 能够在发送查询请求时指定要返回哪些数据,未指定的不返回,知足了手机端只须要少许数据的要求。
  2. 能够在一次查询中同时请求多个后端服务,将多个服务的查询结果聚合后返回,而不须要新增聚合服务或者屡次调用不一样的后端服务后获得想要的数据。

有了以上能力,前端就能够根据已有的后端服务和实际业务要求灵活定制查询请求,不用再去麻烦后端哥哥开发新的服务了。web

2、Spring集成GraphQL

  1. pom文件添加如下依赖:
<!-- 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>
复制代码
  1. 查询服务
    须要支持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注解。spring

  1. 配置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
}
复制代码
  1. 查询方法配置,这些查询方法和实际查询方法对应,入参和出参保持一致。
type Query {
    findBooks: [Book]
    findBook(id:Int):Book findDog(name: String!):Dog findDogByName(name: String!):Dog } 复制代码

以上完成以后就可使用查询服务了。后端

3、测试工具

GraphQL自带了一个测试工具,浏览器中输入: http://localhost:7000/graphiql 打开测试工具界面。(注:端口号为spring端口号,请自行修改)。浏览器


左边是查询请求,右边是返回结果,能够看到在查询请求中:

  1. 指定了查询参数
  2. 指定了要返回的字段
  3. 聚合了findBook和findDogByName两个后端服务

完美实现了以前咱们提到的两点要求。bash

4、和Controler共存

在引入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.app

完整实例代码扫码加入微信公众号并回复:webfullstack,获取仓库地址。spring-boot

<---左边点赞!


站点: javashizhan.com/


微信公众号:

相关文章
相关标签/搜索