dgs-framework
dgs-framework copied to clipboard
Integrate Spring Graphql with DGS Framework
The DGS and Spring-GraphQL teams are super excited to introduce deep integration between the DGS framework and Spring-GraphQL. This will bring the community together, and we can continue building the best possible GraphQL framework for Spring Boot in the future.
Getting Started with DGS/Spring-GraphQL
Continue reading to learn how we got here, and why it's so exciting, but if you want to get started, here is how.
You can opt-in to use DGS/Spring-GraphQL by replacing the starter dependency.
Replace implementation "com.netflix.graphql.dgs:graphql-dgs-spring-boot-starter"
with implementation "com.netflix.graphql.dgs:graphql-dgs-spring-graphql-starter"
.
You also need to add either Spring WebMVC or Spring WebFlux explicitly.
With this integration, it is technically possible to mix and match the DGS/Spring-GraphQL programming models. However, to maintain consistency in your codebase and to take full advantage of DGS features, we recommend sticking with the DGS programming model. Additional features from spring-graphql will be available via existing spring-graphql extensions, such as multipart-spring-graphql and the Subscription Callback mechanism in the JVM Federation library.
Background - Two competing frameworks
The DGS Framework provides Java developers with a programming model on top of Spring Boot to create GraphQL services. Netflix open-sourced the DGS framework in 2021, and has been the widely adopted GraphQL Java framework by many companies.
While we continued adoption and development on the DGS Framework, the team at Spring were also exploring GraphQL support for Spring Boot. This effort was already underway prior to open-sourcing the DGS framework, while the Spring GraphQL efforts were also yet to be announced. After open sourcing the framework, both teams convened to discuss the current state and future direction. At the time Spring GraphQL was not as feature rich in comparison to the DGS Framework and we both decided to continue what we were doing. While both the frameworks started with different goals and approaches, over the past year, Spring-GraphQL has matured and reached feature parity with many aspects of the DGS framework. This resulted in two "competing" frameworks in the community that largely solved the same problem.
Today, new users must choose between one or the other, raising questions about which framework to adopt. It might also mean missing out on features available in one framework but not the other. This is not an ideal situation for the Java/GraphQL community.
For the maintainers of both frameworks, it would be much more efficient to collaborate on features and improvements instead of having to solve the same problem twice. Notably, bringing the communities together is a highly desirable goal!
Why not just EOL one of the frameworks?
The DGS framework is widely used and plays a vital role in the architecture of many companies, including Netflix. Moving away from the framework in favor of Spring-GraphQL would be a costly migration without any real benefits.
Although Spring-GraphQL doesn't have the user base of DGS, it makes sense from a Spring Framework perspective to have an out-of-the-box GraphQL offering, just like Spring supports REST.
The way forward
@srinivasankavitha and @paulbakker from the DGS team have worked together with Rossen Stoyanchev and Brian Clozel from the Spring-GraphQL team on integration between the frameworks. Special thanks to @kilink for being our first early adopter and contributing many bug fixes and performance improvements as part of this effort.
With this integration, you can pull in additional features from Spring GraphQL. We also eliminate the need for part of the DGS code that integrates the framework with Spring MVC/WebFlux, since there isn't much benefit to duplicating low level functionality.
For the near term, the DGS/Spring-Graphql integration will be available as an opt-in feature via a different spring-graphql flavor of the DGS starter. We plan to make this the default mode in the long term after we see some level of successful adoption.
Technical implementation
Both DGS and Spring-GraphQL are designed with modularity and extensibility in mind. This makes it feasible to integrate the two frameworks. The following diagrams show how the frameworks are integrated at a high level.
Today, the DGS framework looks as follows.
A user uses the DGS programming model, such as @DgsComponent
and @DgsQuery
to define data fetchers etc.
A GraphQL query comes in through either WebMVC or WebFlux, and is executed by the DgsQueryExecutor
, which builds on the graphql-java library to execute the query.
The DgsQueryExecutor
is also used directly when writing tests.
With the Spring-GraphQL integration, a user can write code with both the DGS programming model and/or the Spring-GraphQL programming model. A GraphQL query comes in through WebMVC/WebFlux/RSocket, which Spring-GraphQL now handles. The representation of the schema (a GraphQLSchema
from graphql-java) is created by the DGS framework, and used by both the DGS and Spring-GraphQL components. Spring-GraphQL's ExecutionGraphQLService
now handles the actual query execution, while the DGS QueryExecutor
becomes a proxy on top of ExecutionGraphQLService
so that existing test code continues to work.
Required Changes
The good news is that the new integration has been mostly a drop-in replacement, not requiring any major code changes for the user. The one exception is the set up of MockMVC tests for GraphQL testing. Since web request processing is now based on async dispatching mechanism, we now require explicit handling for this in the test setup. Instead, you can also use the recommended HttpGraphQlTester
with @MockMvc
available in Spring GraphQL to achieve the same.
Known Gaps
At this time, we are lacking support for SSE based subscriptions and Persisted Queries. These are on the roadmap and will be made available depending on support in spring-graphql.
Performance
At Netflix, we tested the DGS/Spring-GraphQL integration on some of our largest services. Surprisingly, we uncovered a few performance issues in Spring WebMVC/Spring GraphQL with this integration. The Spring team has quickly addressed these issues, and the performance is now even better compared to baseline performance of Netflix applications with just the regular DGS Framework.
Configuration
There is some overlap between configuration properties for DGS and Spring-GraphQL. Where properties overlap, we use the DGS property for the best backward compatibility. The following list is the overlapping properties.
DGS property | Spring-GraphQL property | What to use |
---|---|---|
dgs.graphql.schema-locations |
spring.graphql.schema.locations |
Use dgs.graphql.schema-locations |
N/A | spring.graphql.schema.fileExtensions |
Not applicable, because dgs.graphql.schema-locations includes the path |
dgs.graphql.graphiql.enabled |
spring.graphql.graphiql.enabled |
Use dgs.graphql.graphiql.enabled |
dgs.graphql.graphiql.path |
spring.graphql.graphiql.path |
Use dgs.graphql.graphiql.path |
dgs.graphql.websocket.connection-init-timeout |
spring.graphql.websocket.connection-init-timeout |
DGS property sets the Spring-GraphQL property |