GraphQL 101
A practical, experience-driven series on building GraphQL APIs β from schema design fundamentals through federated microservices using TypeScript and Python in production.
Why This Series?
I came to GraphQL after spending years building REST APIs. REST worked well for standard CRUD but became painful when a frontend team wanted different field subsets, or when a mobile app needed to reduce the number of round-trips on a slow network. The classic REST problem: either overfetch (the endpoint returns more than needed) or underfetch (you need five endpoints to build one screen).
GraphQL solves this by letting clients request exactly the fields they need. Once I understood the type system, resolvers, and the DataLoader pattern, I stopped writing endpoint after endpoint and started thinking in graphs.
This series documents what I learned building a real project: a TypeScript-based GraphQL gateway that federates data from multiple microservices β one in TypeScript (the primary service) and one in Python using Strawberry (a catalogue service). Federation is where GraphQL goes from useful to genuinely powerful in a microservices architecture.
What You'll Learn
Understand GraphQL's type system: types, interfaces, unions, enums, scalars, and directives
Design schemas that are easy to evolve without versioning
Build a production-grade GraphQL server with TypeScript and Apollo Server 4
Build a Python GraphQL subgraph with Strawberry
Write queries, mutations, and real-time subscriptions
Authenticate and authorise requests at the field and type level
Federate multiple GraphQL services into a single API graph
Solve the N+1 problem with DataLoader
Test resolvers and federated schemas with Jest and pytest
Deploy and monitor GraphQL services in production
Technology Stack
TypeScript Services
Runtime: Node.js 20+
Language: TypeScript 5.x
GraphQL Server: Apollo Server 4
Schema: Schema-first SDL +
graphql-tagFederation: Apollo Federation v2 (
@apollo/subgraph, Apollo Router)ORM: Prisma 5 (PostgreSQL)
Data loading: DataLoader
Auth: JWT (
jsonwebtoken), bcryptValidation: Zod
Testing: Jest,
@apollo/server/testingSubscriptions:
graphql-wsover WebSocket
Python Service
Language: Python 3.11+
GraphQL Server: Strawberry (code-first, fully typed)
Federation: Strawberry Apollo Federation extension
Web framework: FastAPI
ORM: SQLAlchemy 2.x (async)
Testing: pytest,
strawberry.testing
Prerequisites
TypeScript and Node.js fundamentals
Python fundamentals (classes, async/await, type annotations)
PostgreSQL basics
Basic Docker knowledge
Series Structure
Understand what GraphQL is, how it fundamentally differs from REST, and how the SDL describes an API. Set up TypeScript and Python environments.
Key Topics:
GraphQL query language and runtime
SDL: types, fields, scalars, non-null
Queries, mutations, and subscriptions explained
REST vs GraphQL tradeoffs β when to use which
Setting up Apollo Server 4 with TypeScript
Master the full GraphQL type system. Design schemas that model real domains correctly and evolve gracefully.
Key Topics:
Object types, interfaces, unions, and enums
Custom scalars (Date, JSON, UUID)
Input types vs output types
Schema-first vs code-first approaches
Naming conventions and schema evolution without versioning
Directives:
@deprecated,@skip,@include, custom directives
Build a complete GraphQL API from scratch with TypeScript, Apollo Server 4, and Prisma. Implement resolvers, context, data sources, and subscriptions.
Key Topics:
Apollo Server 4 project structure
Resolver chain execution
Context: database client, auth user, data loaders
Solving the N+1 problem with DataLoader
Mutations with input validation (Zod)
Real-time subscriptions with
graphql-ws
Consume GraphQL APIs from both TypeScript frontends and Python backend services. Cover code generation, type-safe queries, and inter-service communication.
Key Topics:
Apollo Client in TypeScript: queries, mutations, cache
GraphQL Code Generator for type-safe TypeScript operations
Python
gqlclient: consuming a GraphQL API from a Python servicePersisted queries and query batching
Error handling on the client side
Secure GraphQL APIs at the operation, type, and field level. Implement JWT authentication and role-based access control without middleware spaghetti.
Key Topics:
JWT authentication with Apollo Server context
Field-level and type-level authorization with custom resolvers
Schema directives for declarative auth (
@auth,@hasRole)Protecting subscriptions
Auth in the Python Strawberry subgraph
Compose TypeScript and Python GraphQL services into a single unified API graph using Apollo Federation v2.
Key Topics:
Federation concepts: subgraphs, supergraph, entities,
@keyTypeScript subgraph with Apollo Server and
@apollo/subgraphPython subgraph with Strawberry and FastAPI
Apollo Router as the composition gateway
Cross-service entity references:
@extends,@externalIncremental migration strategy from monolith to federated graph
Test GraphQL resolvers thoroughly, optimise for production load, and deploy with observability.
Key Topics:
Unit testing resolvers with Jest and Apollo's
executeOperationIntegration testing with real database (Testcontainers)
Python subgraph testing with
strawberry.testingPersisted queries for production performance
Query complexity analysis and depth limiting (security)
Deployment: Docker, environment variables, Apollo Studio
Distributed tracing with OpenTelemetry
Getting Started
TypeScript Setup
Python Setup
Jump to Part 1 to begin.
Last updated