Why GraphQL Is Perfect For Microservices
Tags: graphql, microservices, typescript
Published: 2021-10-13 00:04:36

A well-designed microservices architecture is an amazing thing. When each service is responsible for its own specific domain and can be deployed independently, it allows for unparalleled flexibility and productivity for backend teams. However, very few decisions are all benefit with no cost - including our decision to choose microservices over a monolithic backend. 

Before we migrated our backend to GraphQL, one trade-off that we encountered was the additional complexity that it imposed on our client-side networking code - especially when we had to create views that used data from multiple services.

For example, our application had a "appointment list" view that looked a little something like this:

![Appointment List View](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oty3u5gwy95r182vhwxa.png)

In a monolithic architecture, the networking code for this page could be trivial. It would be very uncommon to look at an appointment without provider, patient, and clinic details, so you probably would want to JOIN those tables in the appointments query and return them every time.

For example:

```
[MONOLITH]: /companies/id/appointments

{ result: [Appointment] } <--- joined with provider/patient info
```

However, this JOIN was not possible in our microservices architecture since Appointment Service does not have access to provider and patient data. 

Our client applications now had to query three different services via four different endpoints instead of querying one resource that returned all the data they needed. Additionally, the client applications did not have access to the IDs of the required providers, patients, and clinics until after we loaded the initial appointments query!

So the client side networking logic ended up looking like this:

```
- [APPOINTMENT SERVICE] - GET /companies/id/appointments

.. wait for data ...

{ result: [Appointment] }

THEN:
- [PATIENT SERVICE] - GET /patients/id x 5
- [COMPANY SERVICE] - GET /clinics/id x 5
- [COMPANY SERVICE] - GET /providers/id x 2
```

Not ideal! The requests were fast, but almost twice as slow as the monolithic version would have been since we had to wait for the initial appointments request to complete before fetching the rest of the associated details.

## GraphQL To The Rescue

We worked around these limitations for a while, but realized that eventually something had to give. The microservices infrastructure that the backend team loved so much was making the developer experience for our frontend and mobile teams extremely frustrating. We needed a solution, and we needed one fast.

Luckily, there was a brand new innovation in the GraphQL ecosystem that was the perfect solution for our problem - Apollo Federation.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/whdb7h64hf5a5hvtwz54.jpeg)

Apollo Federation allowed each microservice to manage its own "subgraph" while abstracting that complexity from our client applications. All our subgraphs were stitched together in the GraphQL Gateway to create one seamless Federated Graph that could easily be accessed via a single endpoint.

The new request for the company appointment list was:
```
- [GRAPHQL GATEWAY] - POST /graphql

query {
  companyAppointments { <--- [APPOINTMENT]
    startTime
    patient { <--- [PATIENT]
      firstName
      lastName
    }
    provider { <--- [COMPANY]
      firstName
      lastName
    }
    clinic { <--- [COMPANY]
      clinicName
      lastName
    }
}
```
Our clients did not need to know which backend service was resolving the data they were querying, and they only had to make one request to complete this view. This new query was also much more efficient because:
- GraphQL only returns the specific fields the client requests, making the payloads much smaller
- The Gateway is able to gather all the data it needs via inter-service communication before responding to the client (eliminating the need for the followup requests)

Thanks to GraphQL Federation, we were able to have our cake and eat it too! The backend team was able to continue development with all the benefits that microservices provide, while our frontend and mobile teams become even more efficient with the flexibility of GraphQL. 

We were extremely happy with the outcome of our migration to Federated GraphQL, and while microservices can be good with REST, they are better with GraphQL!