The Evolution of APIs — Our Road to GraphQL Federation
This is the story of how APIs aggregation at Alef platform was evolved & the experiences we had through out the years since we started our very first student app. I will not go into details & specifics but if you want to know any specific details just leave a comment below & I will be happy to answer.
A Star is Born
Mid 2017 when ALEF Education was just a startup, we were working on our very first student learning platform app. Following our old traditions, we started with a very simple frontend app with brand new micro-services
Life was good. We were consuming very few APIs therefore we were not bothered too much about the number of APIs that we needed to aggregate on our frontend.
Trouble with multiple APIs
As the project grew, we had multiple frontends which were interacting with our micro-services. The number of micro-services also grew along with that. The struggle started when frontend developers needed to aggregated multiple APIs to meet their use cases
Frontend developers usually love the simplicity of working with a single API to meet their needs. But on the other hand, backend developers love the decoupling & flexibility of APIs that they develop.
BFF Layer
To solve this API aggregation problem, we brainstormed a bit & concluded to introduce a BFF (backend-for-frontend) layer. This allowed us to call a single endpoint on our frontends for each of our use case.
At least now the frontend developers were happy as they had to consume a single API to meet their use cases. But not for long...
Here Comes the GraphQL
Meanwhile GraphQL was also in the market & we thought why not make use of it as it was specifically introduced to solve the problem that we were having. Along with that it has a lot of advantages.
- Client can fetch only the data they need hence it’s faster
- Single API to consume
- Auto caching capability
And the list goes on. We used Apollo Client on our frontends which enabled clients to fetch only the data that the client need. We also loved its caching capabilities on the frontend. So we implement our BFF layer as a graphQL service.
It was a life saver. A single graph service as our BFF for all our frontends. Looking good right? Well…
A Monolith is Born
The graphQL service as BFF worked for us for years. Throughout these years, the company grew significantly & number of teams managing different modules / services also grew along with it.
More & more people were contributing to our graphQL BFF layer. This started worrying us as it started to look like a big monolith.
This resulted in following issues for us:
- A single point of failure
- Hard to maintain & release
- More git merge conflicts
- No clear ownership
Going Back to our Rich History
To deal with these bottlenecks, looking at our core principles of micro-services, we decided to break the monolith into smaller graph services.
The clients were pointing to multiple graph services to meet their use cases. At this point the Schema Stitching from GraphQL was also in the market but it was doing pretty much the same thing that we already came up with, so we decided to stick with our own solution.
Chaos on the Frontend
While all this was happening, we were also making use of the graphQL schema on our frontends. We were downloading graphQL SDL schema files from different graphQL services & merging into a single SDL file. Then it was being used for:
- Validate client operations
- Auto generate typescript types
- Auto generate react hooks & HOCs for graphQL query or mutation
The trouble started when two graphQL services started to define a type, query or mutation with the same name. This caused schema conflicts on the frontend. There was no clear communication between different graphQL service owners on how the types, queries or mutations should be named. It was a complete chaos on our frontends.
To deal with this chaos, we had to communicate back & forth to make sure there were no type, query or mutation conflicts whenever there was a change in the schema of any graphQL service.
GraphQL Federation to the Rescue
Meanwhile GraphQL Federation Specs was released by Apollo to solve all those problems that we were having. It was a perfect solution for us. But migrating our existing graphQL services to GraphQL federation specs was also a headache since at this point we had multiple graphQL services. But thanks to pioneers of Apollo GraphQL who made the process of migration very smooth.
We bought a plan with Apollo Studio (previously known as Apollo Engine) & implemented our graphQL gateway layer. It took us sometime to put all of our subgraphs behind our graphQL gateway.
Finally we had the perfect solution. No more chaos on the frontend. We were able to detect any schema composition errors before it was published to Apollo schema registry through Apollo’s schema check command.
We stick with Apollo Studio for a long time but recently we had to move to GraphQL Hive. I will share that experience in another story.