GraphQL APIs

GraphQL is a query language for APIs where the client asks for exactly the fields it needs from a single, strongly typed endpoint, and the server answers using one resolver function per field.

Learn GraphQL APIs in our free Node.js course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Node.js course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll compare GraphQL with REST, write a schema with types, queries, and mutations, understand how resolvers fetch each field, see the core query executor in action, and wire it all together with Apollo Server.

What You'll Learn in This Lesson

1️⃣ GraphQL vs REST: the Schema

A GraphQL API starts with a schema written in the Schema Definition Language (SDL). It declares your types (like User ), the readable fields under type Query , and the write operations under type Mutation . A ! marks a field as non-null (required).

Where REST might force you to call /users/1 and get the whole record, a GraphQL query names just the fields it wants — so the client decides the response shape, avoiding both over-fetching and under-fetching.

2️⃣ Resolvers: How Fields Get Their Values

The schema says what exists; resolvers say how to fetch it. A resolver is one function per field that returns its value — from a database, another API, or an array. GraphQL then keeps only the fields the client asked for. The runnable executor below models exactly that: it resolves the data, then picks just the requested fields .

3️⃣ The Real Thing: Apollo Server

In production you hand your typeDefs (the SDL) and your resolvers to Apollo Server , which parses each incoming query, validates it against the schema, calls the right resolvers, and assembles the response — plus a sandbox UI for exploring your API. Notice resolvers are grouped under Query and Mutation , and each receives (parent, args, context) .

Your turn. The executor below works once you fill in the field list marked ___ . Follow the 👉 hint, then run it.

No blanks — just a brief and an outline. Build a resolver map with a Query.todos reader and a Mutation.addTodo writer, then show the list growing. Run it and compare with the example output.

📋 Quick Reference — GraphQL Building Blocks

Practice quiz

What is a key advantage of GraphQL over a typical REST endpoint?

  • It requires no server
  • The client asks for exactly the fields it wants
  • It only returns XML
  • It cannot be queried

Answer: The client asks for exactly the fields it wants. A GraphQL client requests precisely the fields it needs, no more, no less.

In GraphQL SDL, what does the ! after a type mean, as in String!?

  • The field is non-null (required)
  • The field is deprecated
  • The field is a list
  • The field is optional

Answer: The field is non-null (required). ! marks a field as non-null, meaning it must always have a value.

What is a resolver in GraphQL?

  • A database table
  • A caching layer
  • A function that returns the value for a field
  • A type definition

Answer: A function that returns the value for a field. Each field has a resolver function that produces its value.

Which special type holds read operations in a GraphQL schema?

  • Mutation
  • Subscription
  • Schema
  • Query

Answer: Query. The Query type defines the fields clients can read/fetch.

Which type is used for operations that CHANGE data, like addUser?

  • Mutation
  • Query
  • Fragment
  • Scalar

Answer: Mutation. The Mutation type defines write operations such as adding a user.

What does the type notation [User!]! describe?

  • A single optional user
  • A non-null list of non-null Users
  • A string of users
  • An empty list

Answer: A non-null list of non-null Users. [User!]! is a required list whose every element is a non-null User.

Which library is shown for building a real GraphQL server in the lesson?

  • Express GraphQL Classic
  • GraphiQL only
  • Apollo Server (@apollo/server)
  • Mongoose

Answer: Apollo Server (@apollo/server). The lesson uses @apollo/server with startStandaloneServer.

How does a client avoid over-fetching with GraphQL?

  • It downloads the whole database
  • The server always sends every field
  • It uses multiple endpoints
  • It lists only the fields it needs in the query

Answer: It lists only the fields it needs in the query. By naming just the fields it wants, the client gets exactly that data.

In Apollo Server, how are resolvers organized?

  • Grouped by type, e.g. Query and Mutation
  • In a single flat array
  • Inside the database
  • As URL routes

Answer: Grouped by type, e.g. Query and Mutation. Resolvers are grouped under Query, Mutation, etc., one function per field.

What is the ID type's role in the User schema?

  • It stores an image
  • It is a unique identifier for the object
  • It is the user's password
  • It is a timestamp

Answer: It is a unique identifier for the object. ID is a scalar serving as a unique identifier for an object.