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/


微信公衆號:

相關文章
相關標籤/搜索