Our engineering team at Knotel was one of the first companies to deploy Apollo Federation into production.
Apollo Federation enables a nice way to expose a single GraphQL data graph to clients while maintaining a clean microservice architecture under the hood. It was Apollo’s follow up to schema stitching and adds a bunch of useful functionality, including the ability to split a single GraphQL typedef across microservices.
This was originally an 18 Tweet Tweetstorm that I have reformatted as a blog post here for readability.
Recently at Knotel we moved our GraphQL server to use the new Apollo feature called Federation.
At its core Federation stitches together many microservices into a single GraphQL graph exposed to clients.
At Knotel we have a microservice architecture but wanted a single GraphQL endpoint any of our client apps could hit to access our entire data graph. We didn’t want a client app to have to talk to 5 different GraphQL endpoints to get its data.
We also didn’t want a monolithic backend architecture because we wanted engineering squads to own their services, to separate concerns, and to have flexibility as to implementation on a per-service basis.
Further, at Knotel our business (providing flexible workspaces) touches many different concerns across the spectrum from finding real estate to construction and design to helping tenants find space to managing space.
We also have internal, customer-facing, and broker-facing products.
tl;dr a monolithic architecture was not optimal for our business case
We tried Schema stitching with Apollo to consolidate microservices into a single graph and found it lacking.
So we set up the microservices with REST and stood up a single GraphQL server which housed all of the typedefs, resolvers, etc. because this was pre-Federation. So we basically rolled our own.
We called this GraphQL server Foundation because it was core to our infrastructure.
This was great for our client apps because they now had a one-stop shop for all their needs (just construct a GraphQL query to hit Foundation and tell it what you need!) but introduced many pain points.
Clients talked GraphQL to Foundation but our microservices were REST so Foundation had a ton of boilerplate code essentially converting GraphQL to REST in our resolvers. We wrote utilities to convert but were engineering our way around the problem.
Federation fixed this as now our microservices speak GraphQL directly and we have been able to drop that translation layer.
Any change to a microservice also required a change to Foundation to update the typedefs and resolvers to match.
This resulted in changes needed in multiple microservices to enact a single change. We had a lot of lockstep deployments as a result, losing some of the benefit of using microservices and landing us in a deployment hell.
Federation fixed this because now only the microservice with the change needs deployment on change*. Changes can be isolated to one Service which can wholly own the business logic, the typedefs, and the resolvers.
note, the Federation service does need to be bounced
We also ran into complications with Authorization because we wanted to define role-based access control (RBAC) at the microservice level but as our Foundation GraphQL server was our gateway, it controlled access.
So we had a fragile scheme of services defining roles and permissions and propagating to Foundation whenever they were updated.
Federation fixed this because now the service which holds the RBAC policies directly receives requests so they can be gated by the service itself.
We also have types we’d like to span microservices to separate concerns and house business logic in the right places. This wasn’t possible with Apollo before Federation cleanly
We hacked it a bit by having all of our types on one server which could then resolve a single type from multiple services, but again this introduced all of the aforementioned mess (one change updates multiple services, requiring lockstep deployments, etc.)
Federation fixed this by giving us an elegant way to split types across services and schema directives make it easy to tell the Federation query planner where to get what without having to write code to do so manually.
Business logic concerns are once again separated!
Overall we’re just getting started with Federation so these are my thoughts a week in (I’m sure we’ll find some pain points once the honeymoon phase wears off).
So far though it’s been rad! We chucked thousands of lines of code and removed a whole service from our infra.
Apollo Federation vastly simplifies our infrastructure, keeps our concerns separated, and fixes a lot of the pain points we encountered trying to deliver a single graph backed by multiple microservices before Federation.