Web Application Stack Travel - Spring Integration GraphQL

Background

When current applications span multiple terminals, problems often arise as follows:

  1. The amount of information that each end needs to acquire is different. For example, because of the size of the display screen, the mobile terminal needs to acquire less data than the PC terminal. If the same interface is shared with the PC terminal, a lot of redundant data will be returned, which will affect the performance.
  2. There are different requirements for data at each end. Sometimes it is necessary to aggregate data of multiple back-end services. Adding a new service in each aggregation scenario will lead to too tight coupling between front-end and back-end. If multiple calls are made, the number of front-end and back-end interactions will increase, which will affect performance.

In order to solve these problems, GraphQL emerges as the times require, and its corresponding capabilities are as follows:

  1. When sending a query request, it can specify which data to return and not return, which meets the requirement that only a small amount of data is needed on the mobile phone.
  2. Multiple back-end services can be requested at the same time in a query, and the query results of multiple services can be aggregated and returned without adding aggregated services or calling different back-end services many times to get the desired data.

With the above capabilities, the front-end can flexibly customize query requests according to the existing back-end services and actual business requirements, without bothering the back-end brother to develop new services.

2. Spring Integration GraphQL

  1. Add the following dependencies to the pom file:
        <!-- 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. Query Service
    A query service supporting GraphQL is needed to implement the GraphQLQueryResolver interface, which is just a declarative interface without any method. The reference code is as follows:
@Component
public class BookQueryResolver implements GraphQLQueryResolver {

	public List<Book> findBooks() {
		Author author = new Author(1, "Lee", 30);
		Book book = new Book(1, "Java 8 actual combat", author, "Electronic Industry Press");
		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 actual combat", author, "Electronic Industry Press");
		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;
		}
	}
}

You can see that the @Component annotation needs to be added to the class.

  1. Configuring GraphQL's schema
    The schema configuration file can be placed in the resources directory. To support queries, there are two types of configurations:
    1) Data object configuration. These data objects correspond to the objects returned by the query service. The fields can be fewer than the actual returned objects, and the undefined ones can not be returned.
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. Query method configuration, these query methods and actual query methods correspond, input and output parameters are consistent.
type Query {
    findBooks: [Book]
    findBook(id:Int):Book
    findDog(name: String!):Dog
    findDogByName(name: String!):Dog
}

After that, you can use the query service.

3. Testing tools

GraphQL comes with a test tool. In the browser, enter http://localhost:7000/graphiql to open the test tool interface. Note: The port number is spring port number, please modify it yourself.


On the left is the query request and on the right is the return result. You can see that in the query request:

  1. Query parameters are specified
  2. Specifies the fields to be returned
  3. Aggregate findBook and findDogByName back-end services

Perfectly fulfilled the two requirements we mentioned before.

Coexistence with Controler

Before the introduction of GraphQL, the front-end and back-end interfaces in spring were connected through Controller. If Controller could be reused, it would not be perfect to rewrite QueryResolver. Practice has proved that the two can coexist as long as the Controller class implements the GraphQLQueryResolver interface, which can support the previous Rest. Interface query can also support GraphQL query. The reference code is as follows:

@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.

The complete example code is scanned to add the Wechat Public Number and reply: webfullstack to get the warehouse address.

Site: http://javashizhan.com/

Wechat Public Number:

Keywords: Java Spring Mobile less

Added by acirilo on Sun, 18 Aug 2019 10:47:00 +0300