Tutorial

Building Your First GraphQL API

Tutorial · Backend Development

Cover: Building Your First GraphQL API

REST gives you fixed endpoints that return fixed shapes of data. GraphQL flips that: the client describes exactly what it wants in a single query, and the server returns exactly that shape — nothing more, nothing less.

Defining a schema

Everything in GraphQL starts with a schema — a contract describing the types your API can return and the queries clients can run.

type Book {
  id: ID!
  title: String!
  author: String!
}

type Query {
  books: [Book!]!
  book(id: ID!): Book
}

The ! marks a field as non-nullable — String! can never come back as null, which is a guarantee REST responses don't give you without extra documentation.

Writing resolvers

A resolver is the function that actually fetches the data for a field in the schema.

const books = [
  { id: '1', title: 'Dune', author: 'Frank Herbert' },
  { id: '2', title: 'Neuromancer', author: 'William Gibson' }
]

const resolvers = {
  Query: {
    books: () => books,
    book: (_, { id }) => books.find(b => b.id === id)
  }
}

Each field in the schema maps to exactly one resolver function — GraphQL calls the right one automatically based on what the client asked for.

The query the client sends

query {
  book(id: "1") {
    title
    author
  }
}

This returns only title and author — not the id, not anything else the type might have. Ask for more fields in the same query and you get them, in the same request, with no extra round-trip.

Where REST still wins. GraphQL shines when clients need flexible, nested data (a mobile app avoiding several REST calls). For simple CRUD over one resource, plain REST is often simpler to build, cache, and debug — there's no rule that says you must pick one exclusively.

Running it

npm install apollo-server graphql
const { ApolloServer } = require('apollo-server')
const server = new ApolloServer({ typeDefs, resolvers })
server.listen().then(({ url }) => console.log(`Ready at ${url}`))

Apollo Server wires the schema and resolvers together and gives you an interactive playground to try queries immediately — a fast feedback loop while you're still learning the syntax.

Comments