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.
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.
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.
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.
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