The evolution of GraphQL Federation – API Gateway
Publication date: June, 30th, 2021
My name is Dan, and I work as a backend engineer. At MoneyFoward‘s Fukuoka development office, I am working on a project to develop new products at the Start-up Studio Department.
In this article, I‘d like to tell you about how our team looked for a solution to API Gateway challenges in a microservices architecture, as well as the GraphQL Federation‘s superiority that we discovered.
And here is the article‘s agenda:
- The world before GraphQL Federation
- The birth of GraphQL
- The launch of GraphQL Federation- “One endpoint to rule them all”
First, I‘d like to present an example of a pattern that we frequently see in microservice architecture.
We have two components in the project to construct the product review system: Frontend and Backend.
In the backend, we divide them into three services by domain and manage the information for each service as follows:
- Users Service: Service to manage the user’s information
- Products Service: Service for managing product information
- Reviews Service: Service that manages the reviews for the product
From there, we can provide the service to meet the following user needs on the Frontend (mobile and web browsers, third-party apps, etc.):
- The needs of users who want to see a list of products
- The needs of users who want to see a review of one specific product
In order to meet these needs, the Frontend has to interact with the group of Backend services.
Then, we come up with these questions:
- How should we interact?
- What kind of problem are we dealing with in this interaction?
- And how to solve those problems?
We list out certain questions like that, then discuss and investigate them with the team.
To address those concerns, we began to explain to the team why we came up with such a solution and what its benefits were.
Now I‘d like to present the outstanding solution that we discovered through the GraphQL Federation.
2. The world before GraphQL Federation
When a developer solves a problem, they first form a hypothesis, and then proceed to find the solution based on how well they understand that hypothesis. They will then testify, put those hypotheses into action, and repeat the Kaizen recycling process until they are able to develop the product. Let‘s look into these PDCA to see if we can solve the API Gateway problem.
2.1. Plan-1: Stringent connection and exchange
According to the graph above, the products are directly linked to a variety of services. Let‘s see what problems we can find with this design.
→ Obviously, this plan has a lot of problems, and it has lost the scalability advantage of microservices.
Now, let‘s look at plan 2, which can solve the problems above!
2.2. Plan-2: API Gateway
In Plan-1, the Front-end and Back-end interactions were separated and it was difficult to manage. To solve this problem, all Front-end and Back-end requests are gathered and processed by a single service. The API Gateway pattern is often used for this purpose.
So, how does API Gateway solve the problem of Plan-1?
There are a variety of API Gateway solutions, and some open-source products have also made their own Gateways, but in this article, I will just briefly explain the structure of the Kong API Gateway, which is popular in the open source world.
Let‘s take a closer look at Kong‘s operation in the Chart above.
To put it simply, Kong‘s responsibility is to (a) receive requests from the Frontend, (b) forward those requests to the appropriate service, and (c) return the response from that service to the originating Frontend application.
- How could this be achieved in (b)?
- The mapping between the URL pattern of the request and the hostPort of each service is stored in API Gateway as a configuration (the routing configuration table in the chart).
- For example: if we receive a request for a path starting with /user/, we pass it to the user service through config
- Requests can be forwarded to the correct destination by the mapping rule.
- Once a new service is created, you just simply add the new rules to the mapping config.
->The more services you add, the more the front end can query the API Gateway without the need to handle the concerns mentioned above!
So, go ahead and confidently build your system with this plan 2!
However, the system is rapidly evolving, and while implementing the above structure, many new needs and problems emerge, which is both exciting and unfortunate. Here are a few examples:
2.3. Plan-3: Backend for frontend – BFF
Let‘s start with problem-1 (How do we handle a request that is to get data across multiple services?) in API Gateway (Plan-2) -> like in Kong.
Let‘s try to apply Kong to the problem-1,Plan-2 in API Gateway (How do we handle a request that is to get data across multiple services?)
- Not only the API Gateway as in Plan-2, which supports routing to the appropriate service, but also implements the necessary business logic in the API Gateway so that the Frontend can get data from multiple services with a single request. Such a thing is called "Backend For frontend."
- Depending on the needs of the Frontend, a request of any complexity can be implemented by sending a request to the BFF for each service, handling the results of each request, and returning the final result to the Frontend.
→ This sounds like a good solution to the problem of getting data across multiple services, doesn‘t it?
However, the structure above has brought up a new problem!
The example I‘ve given in this article has only three services, but let‘s assume that the product‘s evolution continues and more and more services are added. The more services are added, the more complex the implementation of the BFF (in the red box in the chart above) becomes. The BFF itself grows and becomes a new monolithic service.
→The advantage of microservices is that they can help you separate services by domain, so each team can work in parallel. This is no longer the case with the BFF structure.
So, it would be great if there was a service that could handle complex needs while retaining the benefits of API Gateway and still keeping the responsibilities that it has to take on to a humble size! And that‘s what the GraphQL Federation can do!
3. The birth of GraphQL
Leaving API Gateway aside for the moment, let‘s take a look at the much-discussed GraphQL API in recent years!
If you‘ve heard of or worked with GraphQL, you may be familiar with the one mentioned in Problem-1 of Plan-2: "It would be nice if the front end got the data it wanted with just one request!" The solution to this problem is one of the advantages of GraphQL.
According to the official GraphQL website, "GraphQL is a query language for your API and a server-side runtime for executing queries using a type system you define for your data."
GraphQL has many advantages, but here we would like to highlight some of the differences between REST and GraphQL from a Frontend perspective:
- Services that provide a REST API have a list of endpoints (URLs), and that list of URLs can handle the resources of the service. Since the Frontend can only use one URL and one HTTP method (such as any get, post, delete, etc.) per request, what a request can do is limited to what that URL and HTTP method can do.
- On the other hand, as shown in the chart above, instead of a list of URLs like REST, a service that provides a GraphQL API has only one URL (/graphql) and an HTTP post method to request that URL. The resources of the service are defined in a descriptive GraphQL Schema (the red box in the figure above). Based on the Schema, the Frontend can ask the query for the required resource and get the corresponding response.
- And so, GraphQL is more flexible than REST.
- For example, with the User Schema in the image above, you can query the request body for any resource you like and get it all in one request! If the Frontend only wanted to get the user‘s id in the request, it would get only the id, and then get the user‘s id, name, and addresses in one request. The query itself is easy to read, the data structure is easy to understand, and it is easy for the front end to handle the data.
Compared to REST, GraphQL also has several disadvantages:
- The GraphQL response status code is always 200, and when it fails, the top-level key in the response is errors. We need to see the value of that key.This requires a change in error handling and monitoring mechanisms.
- GraphQL just uses the POST method with only one URL, so it can regain the resource by HTTP Caching. But instead, GraphQL itself has a caching structure for globally unique IDs.
4. Plan-4: The Launch of GraphQL Federation “One endpoint to rule them all”
As explained above, GraphQL was only one of the services.
GraphQL still has many advantages:
- You can get exactly the data you want by requesting it as a query.
- The API Schema itself is descriptive and easy to understand what the service provides.
- We can get all the data we want just with one request!
- These advantages would be great if multiple services could offer them on the Frontend!
- Don‘t you think it would be great if these advantages could be provided to the Frontend for multiple services as well!
That‘s what the GraphQL Federation can do.
GraphQL Federation was created by the ApolloGraphQL company in 2019. The largest system to date to use Federation may belong to Netflix.
The theory behind GraphQL Federation‘s infrastructure can be found here: https://principledgraphql.com/
You can refer to this "https://principledgraphql.com/" to learn more about the logic behind the infrastructure of the GraphQL Federation.
To summarize, GraphQL Federation can be developed in parallel on the backend, with each service focusing on its own domain, and automatically provides a single GraphQL API to the frontend that is aggregated into a single service.
Let’s see what kind of problems API Gateway and BFF can be solved by the GraphQL Federation.
As mentioned above, to implement GraphQL Federation, each service must also provide an API in GraphQL on the Frontend. Existing services must be converted to GraphQL if they are REST. The conversion gives us the overwhelming advantages of GraphQL and GraphQL Federation:
- Teams and services can work in parallel to develop better products at a faster speed.
- The Frontend can utilize Federation‘s API Gateway APIs as part of the service groups without having to be aware of them.
In addition to the more detailed topics listed below, I‘ll go over GraphQL Federation in greater depth in the following post! because my article was too long.
- What makes GraphQL Federation so superior?
- How can we achieve such things?
- How to implement them?
And I‘ll return to the topic of "API Gateway Evolution" soon.