Cant find the role you’re looking for?
Sign up to be the first to know about future job openings at GetYourGuide
Stay notified of new jobsCopyrighted 2008 – 2023 GetYourGuide. Made in Zurich & Berlin.
Manasi Yeole and Usama Nasir from our engineering team share insights on the transformative journey of implementing GraphQL Federation Architecture. Discover how our team successfully migrated from a monolithic structure to a service-oriented architecture, overcame challenges in API aggregation, and embraced innovative solutions to enhance developer experience and system efficiency.
{{divider}}
In Supplier Tech, back in 2021, as we started migrating our monolith to a service-oriented architecture, we realized the need for a unified API aggregation layer at the edge.
We have three different portals communicating with Supplier data across five teams. We could have built a custom aggregation layer for each portal, similar to the one in our traveler tech. However, that would have led to duplicate code in multiple aggregation layers. Considering the advantages GraphQL offers, such as strict schema checks, a supergraph with the option to expose only relevant parts to specific clients, and the tooling provided by Apollo GraphQL, we decided to develop a federated GraphQL platform to power the API layer and simplify UI integration with the backend.
By the end of 2022, we had carved out partially two services from our monolith & the architecture looked like below:
We built a separate layer in front of our monolith(fish farm) and other services for the Subgraphs. As most of the logic was still within the monolith, we built a separate layer of subgraphs. Adding this layer required corresponding schema definitions, which prompted us to identify domain boundaries using these definitions. This exercise was immensely useful in guiding our migration from the monolith into domain services.
At this point, most API calls communicated directly with the monolith, and about 20% of traffic went through the GraphQL implementation to reach the domain services.
Some of the benefits of this approach were:
This design served its purpose well until the full-fledged migration from the monolith in April 2023.
In Q2 2023, we set aggressive targets to transition the Supplier domain from the monolith to domain services and route all traffic from our Supplier and Admin portals through GraphQL. Broken down in steps:
While migrating a couple of APIs, we realized they were meant to facilitate the front end rather than any other backend service. We have found that having an idempotent Subgraph layer that requires backing by a new RESTful API implementation to serve data to the front end is redundant. The picture below illustrates this realization.
This architecture required us to write a lot of boilerplate code in domain service and subgraph, which led to extra effort and delivery delays.
At GetYourGuide, we have cross-functional communities for the leading technologies we use to build our product. We call them Guilds.
We in the GraphQL guild decided that APIs meant to share data with frontends should communicate directly in Graph language rather than REST. This led to a shift in architecture where domain services could become the subgraphs.
Since most of our domain services are in Java, we searched for the best GraphQL framework within Java services. We also aimed to ensure that we could enjoy features similar to those we had with TypeScript and access to various third-party libraries.
We conducted a proof of concept with DGS (Netflix’s GraphQL Spring Boot) and discovered that it simplifies building GraphQL with Java and Spring Boot. It offers annotation-based programming, the ability to generate types from the schema, and the facilitation of testing graph changes by integrating with GraphiQL (the query editor for GraphQL).
The benefits were so apparent that we quickly agreed to proceed with the new architecture change. The architecture after the changes looks like below:
One advantage of the old architecture was the ease of sharing code between subgraphs, as subgraphs were co-located in a mono repo with shared packages. Code sharing was not as trivial as we moved subgraphs to the domain services with separate repositories. We recognized that the authorization logic was a common thread across multiple services and wanted to avoid duplication.
We extracted the authorization logic from our first DGS implementation into a standalone Java library to address this. This library is a centralized hub for authorizing graph requests across all our Java services. By abstracting this functionality, we reduced redundancy and enhanced maintainability and scalability. This further helped teams to focus only on implementing the subgraph business logic and leaving the cross-cutting concerns to the shared library.
In summary, our journey with GraphQL at GYG has been about adapting our architecture to suit our needs better. Starting with the realization of GraphQL’s benefits back in 2021, we’ve continually refined our approach as we migrated from a monolith to domain services. Simplifying the architecture has enhanced the developer experience and efficiency, allowing us to meet the needs of our evolving system better.
To GraphQL guild members Can Cikis and Goncalo Tavares, thank you for contributing and supporting GraphQL architecture improvements and adaptation at GYG.