Apollo Federation support in Graphene

Igor Kasianov
Preply Engineering Blog
3 min readDec 11, 2019

My name is Igor Kasianov and I’m a lead on the backend team @Preply. In this article, I’ll share our experience connecting Python-based GQL graphs in Federated Graph with @apollo/gateway

Background

Preply’s backend was originally built as a monolith application in Python, we’ve adopted GQL API since 2017. In late 2018, we decided to migrate to a microservices architecture.

During the migration, we faced a challenge: how could we keep one single GQL endpoint for frontend after we transitioned to independent graphs for each backend microservice?

GQL schema stitcher: our first try

At the time, Apollo had just released their GQL schema stitcher. It looked like a promising way to combine graphs.

As we played with it, we discovered that all stitching logic was located in the API gateway services. This meant that we would need to update the GQL stitcher service code every time we updated or added a service. Even if we only had 2 nodes, MessageNode and FileNode, the API gateway would become too big.

The API gateway code was bulky and ruined the most important benefits of a microservices architecture — clear code ownership and a loosely coupled codebase.

You can check whole stitcher code example here

Apollo Federation: a perfect solution?

When Apollo Federation was released, it looked like the perfect solution. There was only one problem: libraries for JS, Java, Ruby & .NET existed, but there was no library for Python. Graphene library, which we’re using for GQL implementation in Python, didn’t support Federation.

Undeterred, we decided to create our own implementation of Graphene-Federation integration. It was quite straightforward based on Apollo Federation specification

Our implementation supports most of Federation spec, except 1 decorator:
@provides

You can install it via pip: pip install graphene-federation

See an example

With Apollo Federation, it’s easy to split a big monolithic graph into a set of small graphs.

Let’s assume we have a graph in the monolith, where root querymessage can have multiple files

monolith.py:

Now we decided to move files in separate microservice

monolith.py

file_microservice.py

  • @key(fields='id') Determines that FileNode can be referenced from other services.
  • @extend(fields='id') Marks FileNode as external. We can add more fields to it if needed.
  • id=external(graphene.Int(required=True)) Marks id as an external field.
  • build_schema does all magic
    it adds _service and _entities fields and resolvers in the schema
    it has the same signature as graphene.Schema

You can find more info in the Core concepts of Apollo Federation docs.

In Federation, the API gateway code looks very simple and doesn’t require any updates when we make changes to underlying microservices.

Could you use graphene-federation?

If you use a SOA with GQL and need to connect your python-backed graphs in one endpoint, feel free to use Federation with graphene-federation.

You can open issues or contribute to graphene-federation.

See another open source project from Preply here: database-anonymizer

--

--