Lab 07: GraphQL Server

Time: 30 minutes | Level: Advanced | Docker: docker run -it --rm node:20-alpine sh

Overview

Build a GraphQL API with graphql-js: SDL schema, resolvers, context, DataLoader (N+1 problem), subscriptions, error handling, and introspection.


Step 1: Setup

cd /tmp && npm init -y --quiet
npm install graphql

Step 2: Schema Definition Language (SDL)

const { buildSchema } = require('graphql');

const schema = buildSchema(`
  # Scalar types
  scalar DateTime
  scalar JSON

  # Enums
  enum Role { ADMIN USER GUEST }
  enum SortOrder { ASC DESC }

  # Types
  type User {
    id: ID!
    name: String!
    email: String!
    role: Role!
    posts: [Post!]!
    createdAt: String
  }

  type Post {
    id: ID!
    title: String!
    content: String!
    published: Boolean!
    author: User!
    tags: [String!]!
  }

  # Input types
  input CreateUserInput {
    name: String!
    email: String!
    role: Role = USER
  }

  input PostFilter {
    published: Boolean
    authorId: ID
    tags: [String!]
  }

  # Query and Mutation
  type Query {
    user(id: ID!): User
    users(role: Role, limit: Int = 10, offset: Int = 0): [User!]!
    post(id: ID!): Post
    posts(filter: PostFilter, sortBy: String, order: SortOrder): [Post!]!
  }

  type Mutation {
    createUser(input: CreateUserInput!): User!
    updateUser(id: ID!, input: CreateUserInput!): User
    deleteUser(id: ID!): Boolean!
    publishPost(id: ID!): Post
  }
`);

Step 3: Resolvers & Root Value


Step 4: Context and DataLoader (N+1 Problem)


Step 5: Error Handling


Step 6: Introspection


Step 7: Subscriptions Concept


Step 8: Capstone — Full GraphQL Demo

📸 Verified Output:


Summary

GraphQL Concept
SDL
Purpose

Type

type User { id: ID! }

Define data shape

Query

type Query { user(id: ID!): User }

Read operations

Mutation

type Mutation { createUser: User! }

Write operations

Subscription

type Subscription { msgAdded: Msg }

Real-time events

Input

input CreateUser { name: String! }

Mutation arguments

Enum

enum Role { ADMIN USER }

Fixed value set

DataLoader

new DataLoader(batchFn)

Batch + cache lookups

Context

3rd resolver arg

Request-scoped data

Introspection

__schema, __type

Schema discovery

Last updated