Know These or You’ll Make Every Mistake I Did

“Resolvers that don’t batch? N+1 queries every time. JWT tokens without proper expiry? Passwords in production logs.”

GraphQL isn’t hard. But there are 10-15 concepts that matter — everything else is noise. Master these, and you’ll build fast, efficient APIs. Skip them, and you’ll spend your life firefighting performance issues.

This isn’t a tutorial. It’s a reference guide to the mental models that make GraphQL work. Read it once, bookmark it, refer back when you’re stuck.


1. GraphQL APIs

GraphQL is a query language for APIs and a runtime for executing those queries. It allows clients to request exactly the data they need, making it more efficient than traditional REST APIs. An API (Application Programming Interface) is a set of rules that allows different software entities to communicate with each other.

2. Real-time Capabilities

This refers to the ability of an application to provide immediate feedback or updates as soon as data changes. In the context of GraphQL, real-time capabilities are often implemented using subscriptions, which allow clients to receive updates whenever specific data changes.

3. Schema

A schema defines the structure of your data and the types of queries you can make. In GraphQL, the schema is a contract between the client and the server, specifying what data can be queried and how.

4. Resolvers

Resolvers are functions that handle the logic for fetching the data specified in a GraphQL query. They map the queries and mutations defined in the schema to the actual data sources.

5. Complex Queries

GraphQL allows you to make complex queries that can include multiple nested fields and relationships. This means you can fetch related data in a single request, reducing the number of API calls needed.

6. N+1 Query Problem

This is a common performance issue where a system makes N additional queries to fetch related data for N items. GraphQL can help mitigate this by allowing you to fetch all related data in a single query.

7. JSON Aggregations

This refers to the ability to aggregate data into JSON format, which can be more efficient for certain types of queries and data structures.

8. Predicate Pushdown

This is a performance optimization technique where filtering conditions (predicates) are pushed down to the database level, reducing the amount of data that needs to be processed by the application.

9. Read Replicas

These are copies of your primary database that can be used to offload read operations, improving performance and scalability.

10. JWT (JSON Web Token)

JWT is a compact, URL-safe means of representing claims to be transferred between two parties. It is often used for authentication and authorization in APIs.

11. Observability and Monitoring

These are practices and tools used to understand the health and performance of your system. Observability involves collecting data from your system, while monitoring involves analyzing that data to detect and diagnose issues.

12. Introspection

In GraphQL, introspection is the ability to query the schema itself to understand what queries and mutations are available. This is useful for tools and developers to explore and understand the API.

13. Key Differences Between REST APIs and GraphQL APIs

13.1. Data Fetching

  • REST API: Uses multiple endpoints to fetch different pieces of data. For example, you might have /users to get user data and /posts to get posts.
  • GraphQL API: Uses a single endpoint to fetch all required data. You can specify exactly what data you need in a single query, reducing the number of requests.

13.2. Flexibility

  • REST API: The server defines the structure of the responses, and clients must adapt to it.
  • GraphQL API: The client defines the structure of the response, requesting only the data it needs.

13.3. Over-fetching and Under-fetching

  • REST API: Can lead to over-fetching (getting more data than needed) or under-fetching (not getting enough data), requiring additional requests.
  • GraphQL API: Eliminates over-fetching and under-fetching by allowing clients to request exactly what they need.

13.4. Versioning

  • REST API: Often requires versioning (e.g., /v1/users, /v2/users) to handle changes in the API.
  • GraphQL API: Avoids versioning by evolving the schema and allowing clients to request specific fields.

14. What is a Mutation?

In GraphQL, a mutation is a type of operation that allows you to modify data on the server (similar to POST, PUT, DELETE in REST). Mutations can create, update, or delete data. Here’s an example:

mutation {
  addUser(name: "John Doe", email: "john@example.com") {
    id
    name
    email
  }
}

This mutation adds a new user and returns the user’s id, name, and email.

15. What is a Subscription?

A subscription in GraphQL is a way to maintain a real-time connection to the server. It allows clients to receive updates whenever specific data changes. This is similar to WebSockets in REST. Here’s an example:

subscription {
  newUser {
    id
    name
    email
  }
}

This subscription listens for new users being added and returns their id, name, and email whenever a new user is created.

16. Analogy Between REST API and GraphQL API

  • REST API: Imagine a restaurant where you have a fixed menu. You can order specific dishes, but you might get more food than you need (over-fetching) or have to place multiple orders to get everything you want (under-fetching).
  • GraphQL API: Imagine a buffet where you can choose exactly what you want and how much of it. You get only what you need in one go, without any excess or need for multiple trips.

17. Summary

  • REST API: Multiple endpoints, fixed responses, potential over/under-fetching, versioning required.
  • GraphQL API: Single endpoint, flexible responses, precise data fetching, no versioning needed.

18. Implementing Mutations in GraphQL Servers

Mutations in GraphQL are used to modify data on the server, similar to how POST, PUT, PATCH, and DELETE requests work in REST APIs. Here’s a step-by-step guide on how mutations are implemented:

  1. Define the Mutation Type in the Schema:
    • In your GraphQL schema, you define a Mutation type alongside the Query type. This type includes fields that represent the operations you can perform to modify data.
    type Mutation {
      addUser(name: String!, email: String!): User
      updateUser(id: ID!, name: String, email: String): User
      deleteUser(id: ID!): User
    }
    
  2. Create Resolver Functions:
    • Resolver functions handle the logic for each mutation. They take the arguments provided in the mutation and perform the necessary operations, such as interacting with a database.
    const resolvers = {
      Mutation: {
        addUser: async (_, { name, email }) => {
          const newUser = { id: generateId(), name, email };
          // Save newUser to the database
          return newUser;
        },
        updateUser: async (_, { id, name, email }) => {
          // Find and update the user in the database
          const updatedUser = { id, name, email };
          return updatedUser;
        },
        deleteUser: async (_, { id }) => {
          // Delete the user from the database
          return { id };
        },
      },
    };
    
  3. Execute the Mutation:
    • Clients can execute mutations by sending a mutation query to the GraphQL server. The server processes the mutation using the defined resolvers and returns the result.
    mutation {
      addUser(name: "John Doe", email: "john@example.com") {
        id
        name
        email
      }
    }
    

19. Equivalent of a REST Endpoint in GraphQL

In REST APIs, you interact with resources through specific endpoints (e.g., /users, /posts). Each endpoint corresponds to a specific resource and HTTP method (GET, POST, PUT, DELETE).

In GraphQL, there is typically a single endpoint (e.g., /graphql) that handles all queries and mutations. Instead of multiple endpoints, GraphQL uses a schema to define the types of data and operations available. Here’s how it compares:

  • REST API:
    • Multiple endpoints: /users, /users/:id, /posts, etc.
    • HTTP methods: GET, POST, PUT, DELETE.
  • GraphQL API:
    • Single endpoint: /graphql.
    • Operations defined in the schema: Query and Mutation types.

20. Example Comparison

  • REST API:
    • GET /users: Fetch all users.
    • POST /users: Create a new user.
    • PUT /users/:id: Update a user.
    • DELETE /users/:id: Delete a user.
  • GraphQL API:
    • Query: Fetch data.
      query {
        users {
          id
          name
          email
        }
      }
      
    • Mutation: Modify data.
      mutation {
        addUser(name: "John Doe", email: "john@example.com") {
          id
          name
          email
        }
      }
      

In summary, while REST APIs use multiple endpoints for different operations, GraphQL consolidates all operations into a single endpoint and uses a schema to define the available queries and mutations¹²³.


Use This Reference When You’re Stuck

Understand Schema and Resolvers, fix the N+1 problem, and use JWT properly. Those four things alone put you in the top 20% of GraphQL devs. Everything else is optimization.


Sources & Further Reading

  1. GraphQL — official specification
  2. How to GraphQL — fullstack tutorial
  3. GraphQL specification
  4. GraphQL mutations — Hasura tutorial

See also: Modernizing Your Skills: Embracing GraphQL (Sep 2024) · Graph API vs GraphQL (Sep 2024) — yes, Microsoft Graph and GraphQL are different beasts.