AboutBlogContact
API DesignOctober 18, 2015 2 min read 18

GraphQL Schema Design: Thinking in Graphs, Not Endpoints (2015)

AunimedaAunimeda
📋 Table of Contents

GraphQL Schema Design: Thinking in Graphs, Not Endpoints

It's 2015, and we're finally seeing an alternative to the "RESTful" sprawl that plagues our mobile apps. GraphQL isn't just a query language; it's a shift in how we model data. Instead of hitting /api/v1/posts/123?include=comments,author, we query a single endpoint and get exactly what we need.

The Relay Connection Pattern

If you're building with Facebook's Relay framework, you can't just return a simple list of items. You need to follow the Connection Pattern for pagination. This uses "Edges" and "Nodes" to allow for cursor-based pagination.

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

type User {
  id: ID!
  username: String
  friends(first: Int, after: String): UserConnection
}

type UserConnection {
  edges: [UserEdge]
  pageInfo: PageInfo!
}

type UserEdge {
  cursor: String!
  node: User
}

type PageInfo {
  hasNextPage: Boolean!
  endCursor: String
}

Why Edges?

You might wonder why we need an Edge object between the Connection and the Node. The edge is the perfect place to put metadata that belongs to the relationship rather than the object itself. For example, in a social network, friendship_date belongs on the edge between two users.

Input Objects for Mutations

When it comes to changing data, don't use flat arguments. Use Input Objects. This makes your mutations more maintainable as your requirements grow.

mutation CreatePost($input: CreatePostInput!) {
  createPost(input: $input) {
    post {
      id
      title
    }
    errors {
      message
    }
  }
}

input CreatePostInput {
  title: String!
  content: String!
  clientMutationId: String # Vital for Relay!
}

The N+1 Problem

The biggest challenge in 2015 is the N+1 problem. If a user has 10 friends, a naive GraphQL implementation will call the User database 11 times. We're starting to see the emergence of DataLoader, a utility that uses the Node.js event loop to batch and cache these requests. It's an essential part of any production GraphQL stack.

Read Also

GraphQL and the N+1 Problem: Solving it with DataLoader (2018)aunimeda
API Design

GraphQL and the N+1 Problem: Solving it with DataLoader (2018)

GraphQL is taking over API design in 2018. But without careful implementation, your resolvers will crush your database with N+1 queries. Facebook's DataLoader is the solution.

Bun: SQLite and the Power of Zero-Overhead FFI (2023)aunimeda
Backend

Bun: SQLite and the Power of Zero-Overhead FFI (2023)

Bun isn't just a fast runtime; its native SQLite implementation and FFI are changing how we think about Node.js performance in 2023.

Qwik: Resumability vs. Hydration (2022)aunimeda
Frontend

Qwik: Resumability vs. Hydration (2022)

Is the era of hydration over? In 2022, Misko Hevery's Qwik introduces 'resumability' to achieve instant-on web apps.

Need IT development for your business?

We build websites, mobile apps and AI solutions. Free consultation.

Get Consultation All articles