I’m pleased to announce that we’ve added the Spring GraphQl project and that the initial milestone for the 1.0 release is available. The project integrates GraphQl Java with Spring and is developed collaboratively between the two teams.
Today is GraphQl Java’s 6th birthday! One of the basic decisions I made from the beginning was to consider any HTTP and IO aspects separately. GraphQl Java was always “just” an engine that executed GraphQl requests. This decision paid off, but the obvious drawback is that you need to create your own HTTP adapter for actual use.
This has led to the creation of numerous GraphQL integrations for Spring over the years, including the GraphQL Java Spring project from the GraphQL Java team. But frankly, I’ve always longed for a first-class Spring integration.
If you want to get started, go to our reference documentation and read the “Boot Starter” section, or run samples.
If you don’t know much about GraphQl, there are some great resources here. You can start at graphql.org/learn.
Second, basic support
Spring GraphQL is considered the successor to the GraphQL Java Spring project of the GraphQL Java team. That’s why our initial collaboration focused on matching this functionality and integrating GraphQl Java and Spring in the best way possible. To do this, we created the following basic support:
- HTTP Handlers – Available for Spring MVC and WebFlux, built on WebMVC and WebFlux functional endpoint APIs.
- WebSocket Handlers — A protocol from GraphQL-WS that supports GraphQL subscription streams.
- Web Interception – The ability to intercept each GraphQL request, check the HTTP header, and modify the GraphQL executionInput or executionResult.
- Boot Starter – Put all of this in one running application.
Beyond that, we started looking at key aspects of security, testing, and metrics.
The URL of the GraphQl endpoint is as easy to secure as ever. For finer grained security, applications can use Spring security annotations on data retrieval methods. This requires the Spring security context to propagate to the data retrieval method, and while GraphQlJava is thread agnostic, the components in execution themselves can be asynchronous and cause thread switches.
This enabled us to add contextual propagation support to the data retrieval component from the Web framework level through the GraphQl engine. This includes the ThreadLocal Context and Reactor Context of the SpringMVC and WebFlux applications, respectively. With these features in place, Spring Security can work without any further specialized integration.
The WebMVC-HTTP and WebFlux-Security examples demonstrate the use of Spring Security.
Four, exception handling
Spring GraphQL enables an application to create multiple separate GraphQLExceptionResolver components to resolve GraphQL error exceptions to be included in the GraphQL response. By default, it also provides an ErrorType that can be used to classify errors that are in a common category, such as BAD_REQUEST, UNAUTHORIZED, NOT_FOUND, or INTERNAL_ERROR.
Five, the test
You can use WebTestClient to test GraphQL requests by simply sending and receiving JSON. However, the specific details of GraphQl make this approach more cumbersome than it should be. This is why Spring GraphQL adds WebGraphQlTester, which defines a workflow for testing GraphQL requests. It has the following advantages:
- Verify that the GraphQl response is correct 200 (OK).
- Verify an unexpected error under the “error” key in the response.
- Decode under the “data” key in the response.
- The different parts of the response are decoded using JSONPath.
- Test the subscription.
So examples of using GraphQlTester can be found at samples.
When the spring-boot-starter-actuator dependency exists, metrics for GraphQL requests are collected, including request and DataFetcher execution times and error counts.
QueryDSL provides a flexible and type-safe way to express query predicates. Spring GraphQL is built on top of the Spring Data QueryDSL Extension and makes it easy to create DataFetchers supported by QueryDSL. It prepares a QueryDSL Predicate from the GraphQ L request parameter and uses it to fetch data, which applies to JPA, MongoDB, and LDAP.
The WebMVC-HTTP example is the QueryDSL used.
Schema priority and Object priority
GraphQl provides a Schema language to help clients create valid requests, enable the GraphiQl UI editor, promote common vocabularies across teams, and more. It also addresses the age-old Schema vs Object first development dilemma.
Our view is that Schema should be developed first. It facilitates communication between people with technical and non-technical backgrounds, facilitates tool use, makes it easier to track changes, and so on. There is also no need for a one-to-one strong mapping between GraphQL Schema and Java types.
That is, there is room for code generation, start, client-side creation of queries, and so on. Frameworks like Netflix DGS have good support for this and can be used with Spring GraphQl.
9. Roadmap and Feedback
We intend to achieve the second milestone before SpringOne on September 2, BBB 3. From early feedback, we have found a number of issues with M2 in the queue, including support for the GraphQl client, BatchLoader registration, file uploads, etc.
The milestone phase will continue until after Spring Boot 2.6 in November, when the Boot Starter plans to move into the Spring Boot repository to be included in Boot 2.7.
Our goal is to have a stable API and enter the RC phase later this year. To do this, we need your feedback. Please try using and creating issues or comment in our Issue Tracker.
For more details on Spring GraphQl’s capabilities, see the reference documentation. GraphQl Java and the Spring team will jointly present at this year’s SpringOne conference, which will again be free to attend via a live webcast. Please register to attend our talks and interact with the speakers and attendees.
The translator said
We’ll also continue to watch and use Spring GraphQl and the Spring ecosystem as a whole. If you have any questions, please feel free to talk to me about WeChat ID: Java Architecture Diary.