GraphQL on Frontend and Backend
The bookshop has a React web app and a Node.js server. The frontend developer thinks in screens ("this card needs a title and an author"), the backend developer thinks in data sources ("books live in Postgres, reviews in another service"). GraphQL is the contract in the middle, and each side has its own job.
The rule
The frontend describes needs; the backend resolves each field.
On the frontend, a component states the data it needs as a query. A GraphQL client library (Apollo Client, Relay and urql are common ones) sends it, usually as an HTTP POST to a single endpoint such as /graphql, with a JSON body:
{ "query": "query { book(id: \"b1\") { title author { name } } }" }Client libraries add three big helpers:
- A normalised cache: objects are stored by type and
id, so if two screens fetch book b1, it is kept once and both update together. - Loading and error states for each query.
- Generated types: tools read the schema and produce TypeScript types for every query, so a typo in a field name fails at build time.
On the backend, a GraphQL server library (such as GraphQL.js, Apollo Server or GraphQL Yoga in JavaScript, graphql-java, Graphene in Python) holds the schema and a map of resolvers, one function per field that needs custom work:
const resolvers = {
Query: {
book: (parent, args, context) => context.db.findBook(args.id),
},
Book: {
author: (book, args, context) => context.db.findAuthor(book.authorId),
},
};A resolver receives the parent object (the value its enclosing field returned), the field's arguments, and a shared context (logged-in user, database handles). Fields without a resolver, like Book.title, use a default that simply reads the property of the same name from the parent.
The shortcut
To see how the server answers, trace the query top-down and ask, for each field, "which resolver, and what parent?"
Query.book
No parent at the root.
args.idis"b1", so it returns the book row{ id, title, price, authorId }.
The trap is thinking the client talks to the database. It never does: it talks to the schema, and the resolvers are free to fetch from anywhere.
Drills
Answer fast — trust the rule.
How does a typical frontend client send a query?
What is the first argument the Book.author resolver receives?
No resolver is written for Book.title. What happens?
Why do client caches store objects by type and id?
Remember
- The frontend describes needs; the backend resolves each field.
- Trace top-down: for each field, which resolver runs and what parent it receives.
- Trap: the client never touches the database; resolvers can fetch from anywhere.
