A Tale of Two Frameworks: The Domain Graph Service Framework Meets Spring GraphQL

Netflix Technology Blog
6 min readApr 8, 2024

--

By Kavitha Srinivasan and Paul Bakker

Netflix open-sourced the Domain Graph Service (DGS) Framework in early 2021. Since then, the framework has seen widespread adoption across Netflix and many other companies. The DGS Framework provides Java developers with a programming model on top of Spring Boot to create GraphQL services.

The DGS Framework comes with many useful features, such as,

You can read our blog post here for a more detailed introduction to the DGS Framework.

Soon after we open-sourced the DGS Framework, we learned about parallel efforts by the Spring team to develop a GraphQL framework for Spring Boot. The Spring GraphQL project was in the early stages at the time and provided a lower level of integration with graphql-java. Over the past year, Spring GraphQL has matured and is mostly at feature parity with the DGS Framework. We now have two competing frameworks that solve the same problem for our users.

Today, new users must choose between the DGS Framework and Spring GraphQL, thus missing out on features available in one framework but not the other. For the DGS and Spring GraphQL maintainers, it would be far more effective to collaborate on features and improvements and provide more robust solutions for the GraphQL community as a whole. Finally, a unified community would provide better channels of feedback.

Why not retire the DGS Framework or Spring GraphQL?

The DGS Framework is widely used and plays a vital role in the architecture of many companies.

At Netflix, hundreds of applications use the DGS Framework and custom instrumentations to integrate with the Netflix ecosystem of metrics, tracing, security, etc. Consequently, the effort and time required to have all our users migrate to an entirely new framework is non-trivial without any real benefits.

From a Spring Boot perspective, it makes sense to have GraphQL support readily available, just like REST, without requiring any third-party framework.

Framework Architecture with Spring GraphQL

Both the DGS Framework and Spring GraphQL are designed on top of graphql-java, the low-level library responsible for executing GraphQL queries. The DGS Framework is highly modular, and the figures below illustrate the layout of the framework before and after integrating with Spring GraphQL.

The core of the framework consists of the DGS API with its annotations, such as the @DgsComponent and @DgsQuery, the DGS Query Executor, and the DGS Schema Provider. The DGS Schema Provider is responsible for loading schema files and wiring up the data fetchers with graphql-java. Finally, the DGS Query Executor executes the queries by invoking graphql-java’s execution engine. The DGS Query Executor API can also be used independently in your tests to execute GraphQL queries.

The framework’s web layers are completely separate from the core. The WebMVC and WebFlux modules receive HTTP/Websocket requests, parse the response, and use the DGS Query Executor to execute a query.

DGS Framework Modules

After integrating with Spring GraphQL, we can now support both the DGS and Spring GraphQL programming models. The DGS Schema Provider is still responsible for wiring up data fetchers for both the DGS Framework and Spring GraphQL. The DGS Query Executor delegates to Spring GraphQL’s execution engine and still exists mainly to preserve backward compatibility for tests. Finally, the handling of requests for WebMVC/WebFlux is completely taken care of by Spring GraphQL and the DGS implementation is no longer used.

We are now able to remove redundant code from the DGS Framework and leverage functionality from Spring GraphQL. Going forward, an additional benefit is that we can avoid reimplementing new features just to maintain feature parity.

DGS Framework with Spring GraphQL Modules

Performance

Some of our largest services, responsible for serving traffic to many devices that watch Netflix, use the DGS Framework. Since performance is critical for these services, we have spent the past years iteratively optimizing the framework for them.

An important release criterion for the DGS Framework with Spring GraphQL integration was to ensure we could adopt it in our services, requiring performance to be on par with the current implementation. We achieved this by running a canary analysis on our largest services, i.e., running two builds, taking production traffic, and comparing key performance metrics. These include CPU utilization, memory usage, and request latencies.

Our initial canary results were poor with CPU degrading by more than 50% and request latencies by 20%. We started seeing better results after several DGS Framework and Spring WebMVC fixes. Despite these improvements, we still saw a 10–20% degradation in CPU.

We realized that we had implicitly switched to asynchronous request processing with the move to use Spring GraphQL’s HTTP handler. Unfortunately, the code of many of our existing services is not explicitly “AsyncAware,” resulting in CPU overhead due to filters being executed multiple times. To preserve the current framework performance, we disabled asynchronous request processing for easier adoption. If needed, you can enable asynchronous request processing with a configuration property.

The DGS Framework with Spring GraphQL is now as performant as our baseline!

What does this mean for my applications?

The DGS Framework with Spring GraphQL integration is designed to be a drop-in replacement for users. The programming model is unchanged, and your code will continue to work the same. The integration is internal and not exposed to the user. If you’re interested in specific Spring GraphQL features, such as Spring Data integration, you can now use them alongside DGS Framework features.

Going Forward

With the release of DGS Framework 8.5.0, our users can access the integration with Spring GraphQL. While this may be the first release with the integration, we’ve spent considerable effort testing our applications to ensure that we have a drop-in replacement for the traditional DGS. More importantly, the performance is also comparable to the traditional DGS, as observed on some of our largest, most complex services at Netflix.

The Spring GraphQL integration is opt-in for users by introducing a new Spring Boot starter. This gives users some time to test the integration of their services. We aim to increase adoption across all services through Q2 2024 at Netflix. Once we have sufficient confidence from existing usage, the Spring GraphQL integration will be the new default in Q3 2024 by modifying the old starter to pull in the new integration.

We intend to remove any legacy code and the legacy starter from our repository before the end of 2024. Although this may seem like an aggressive timeline, we’re confident that changes to user code will not be necessary in almost all cases or will be minimal.

Timeline for Adoption

We will continue to evolve the framework in close collaboration with the Spring team, combining forces to provide the best possible GraphQL support for Spring Boot.

Try it!

You can opt-in to use DGS with Spring GraphQL by replacing the starter dependency. Have a look at the documentation for further details.

Acknowledgments

Thanks to Rossen Stoyanchev and Brian Clozel from the Spring GraphQL team for their close collaboration over the past several months on integrating the frameworks. Thanks to Patrick Strawderman for being our first beta tester with the services his team owns at Netflix and for all his help analyzing and fixing many performance issues. Finally, we’d like to acknowledge the Spring team for their quick turnaround in fixing issues in the core Spring Framework.

--

--

Netflix Technology Blog

Learn more about how Netflix designs, builds, and operates our systems and engineering organizations