Lab 08: GraphQL Architecture

Time: 60 minutes | Level: Architect | Docker: node:20-alpine

Overview

Type-safe GraphQL with Pothos schema builder (code-first), GraphQL Yoga server, DataLoader for N+1 prevention, generated types via graphql-code-generator, and gql.tada for type-safe client queries.


Step 1: Pothos — Code-First Schema Builder

import SchemaBuilder from '@pothos/core';

interface Types {
  Objects: {
    User:  User;
    Post:  Post;
    Query: {};
  };
  Scalars: {
    Date: { Input: Date; Output: Date };
  };
  Context: {
    userId: string;
    db: Database;
    loaders: DataLoaders;
  };
}

const builder = new SchemaBuilder<Types>({});

// Define types — fully inferred from TypeScript interfaces
builder.objectType('User', {
  description: 'A registered user',
  fields: (t) => ({
    id:    t.exposeString('id'),
    name:  t.exposeString('name'),
    email: t.exposeString('email'),
    // Computed field
    displayName: t.field({
      type: 'String',
      resolve: (user) => `${user.name} <${user.email}>`,
    }),
    // Relation — loaded via DataLoader
    posts: t.field({
      type: ['Post'],
      resolve: (user, _args, ctx) => ctx.loaders.postsByUserId.load(user.id),
    }),
  }),
});

Step 2: Queries and Mutations


Step 3: DataLoader — N+1 Prevention


Step 4: GraphQL Yoga Server


Step 5: Type-Safe Client with gql.tada


Step 6: graphql-code-generator


Step 7: Input Validation at Schema Level


Step 8: Capstone — GraphQL Schema Execution

(gql.js runs the schema execution)

📸 Verified Output:


Summary

Feature
Tool
Benefit

Code-first schema

Pothos

Types inferred from TS

N+1 prevention

DataLoader

Batch + cache per request

Server

GraphQL Yoga

Modern, pluggable

Type-safe client

gql.tada

No codegen step needed

Code generation

graphql-code-generator

Typed hooks + operations

Validation

Zod in resolvers

Runtime + type safety

Depth limit

Yoga plugin

DoS prevention

Persisted queries

Yoga plugin

Production security

Last updated