GraphQL at Twitter

By @beyang on October 27, 2017

Tom Ashworth (@tgvashworth) is a software engineer on the core services team at Twitter.

Tom's going to give us a whirlwind tour of how GraphQL fits into the architecture at Twitter. We're going to cover:

  • The Twitter GraphQL API and how it fits into Twitter's microservices architecture
  • Subscriptions architecture
  • Twitter's schema and plan for GraphQL in the long term

API

Twitter started experimenting with GraphQL two years ago:

  • Dec 2016 Tweet deck
  • Feb 2017: Twitter light
  • 2017: Twitter frontend

Twitter is famously a microservices company. He counted the number of configuration files in their monorepo and they numbered over 2000.

Here's a high level overview of the backend architecture at Twitter, pre-GraphQL:

gql 7

At a high level, there are 2 types of services:

  • HTTP services
  • Thrift services

Communication between microservices is typed via Thrift.

And here is where the GraphQL API fits in as an HTTP and Thrift service:

gql 8

Let's dive into some of the challenges of implementing GraphQL at Twitter. One challenge is monitoring. IN HTTP services, errors are easy to detect in the HTTP error codes. However GraphQL is capable of partial successes. GraphQL requests almost always succeed with a 200 even if part of the query failed.

So instead of HTTP error codes, they track the number of the exceptions per query.

They also use GraphQL-specific defenses. Imagine a pathologically nested query:

{
  user(rest_id: "12") {
    name
    followers {
      name
      followers {
        name
        followers {
          name
        }
      }
    }
  }
}

They assign a point value to each level of nesting and limit queries to some max point value.

They don't allow arbitrary queries. All queries must be uploaded and stored ahead of time and exchanged for a unique key:

POST /graphql/eyBuaWNlIHsgdHJ5IH0gfQ

Twitter Frontend (TFE) serves as a proxy to all incoming traffice. It talks to the GraphQL API (in addition to the other HTTP API services):

gql 16

gql 17

TFE is responsible for user authentication. The lower-level services are responsible for authorization (permissions) checks. Thus, the GraphQL API server does not need to concern itself with any authn or authz checks.

Subscriptions

Clients subscribe to an event with a GraphQL query and receive payloads.

The subscriptions service is separate from the GraphQL API.

There are 3 parts to subscriptions:

  1. Event production
  2. Query execution
  3. Delivery

Query execution

  "query": "subscription { random_tweet { id } }",
  "user": {
    "id": "12"
  },
  "event": {
    "type": "random_tweet",
    "tweet_id": "..."
  }
}

Delivery

gql 24 gql 25 gql 26

Event production

gql 28 gql 29

Putting it all together:

gql 30

Schema

Strato is a kind of virtual database (federated) that brings together multiple data sources so they can be queried and mutated uniformly.

Strato has existed at Twitter much longer than GraphQL and gives them end-to-end types from database to the client. It is a technology internal to Twitter and there are no plans to open source it. It is similar in spirit to many of the other technologies presented at this conference that stitch together multiple data sources into a single source of truth.

gql 33

Here's how GraphQL fits into Strato types:

gql 35