GraphQL APIs in PHP
GraphQL is a query language for APIs that lets clients ask for exactly the data they need from a single endpoint. In this lesson you'll design a typed schema , write queries and mutations , back fields with resolvers using webonyx/graphql-php , and see why it solves REST's over- and under-fetching.
Learn GraphQL APIs in PHP in our free PHP course — an interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Php course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ The Schema: A Typed Contract
Everything in GraphQL starts with the schema , written in the Schema Definition Language (SDL) . It declares your types (like User and Post ), their fields, and the relationships between them. Two special types are the entry points: Query lists every read operation, and Mutation lists every write. A trailing ! marks a field as non-nullable. Because the schema is typed, the server can validate any incoming query before running a line of resolver code.
This one document is the whole API's contract. It also self-documents: tools can read it to give clients autocompletion and validation, which is a big part of GraphQL's appeal.
2️⃣ Queries: Reading Exactly What You Need
A query reads data. The client writes the shape it wants — which fields, and how deep — and the server returns JSON in exactly that shape. Ask for three fields and you get three fields; ask for nested posts and they come back inside the user. This is the heart of GraphQL: the client controls the response shape, so there are no wasted bytes and no second request for related data.
Notice how the response mirrors the request one-to-one. That predictability makes GraphQL responses easy to consume on the client.
3️⃣ Mutations: Changing Data
Reads use queries; anything that changes data uses a mutation — creating, updating, or deleting. The syntax is nearly identical, but the operation keyword is mutation , and it maps to a field on the special Mutation type. Usefully, a mutation returns data too: you pick which fields of the newly changed object to read back, so a create can immediately hand you the new id .
Keeping reads (queries) and writes (mutations) separate is a clear, enforced convention — the schema makes it impossible to accidentally mutate data from a query.
4️⃣ Resolvers: Where PHP Does the Work
A schema describes what is possible; resolvers implement how . Every field is backed by a resolver function that returns its value — usually by reading a database, calling a service, or following a relationship. In PHP the standard engine is webonyx/graphql-php ( composer require webonyx/graphql-php ): you define types and their resolve callbacks, build a Schema , and call GraphQL::executeQuery() with the incoming query.
For Laravel, Lighthouse builds on this engine with a schema-first, directive-driven style so you write far less of this wiring by hand — but knowing the raw resolver model first means you understand what it's doing.
5️⃣ Why GraphQL? Over- and Under-Fetching
The clearest reason to reach for GraphQL is the data-fetching problem REST runs into. With REST, each endpoint returns a fixed shape : a screen that needs a user plus their posts plus comments often means several requests ( under-fetching ), while an endpoint that returns every field forces clients to download data they'll never show ( over-fetching ). GraphQL collapses that into one request against one endpoint, returning precisely the fields asked for.
Now you try the two core skills — finishing a schema and writing a query. Fill in each ___ using the 👉 hint, then check it against the Output panel.
One more. Write the smallest possible query that asks for just one field.
📋 Quick Reference — GraphQL in PHP
No code is filled in this time — just a brief and an outline. Build it with webonyx/graphql-php : define a Todo type, a query that lists todos, and a mutation that adds one, then wire the single endpoint. This is the full read-and-write GraphQL loop you'll use in real services.
Practice quiz
How many HTTP endpoints does a typical GraphQL API expose?
- One endpoint for everything (usually /graphql)
- One per resource, like REST
- Two: one read, one write
- One per field
Answer: One endpoint for everything (usually /graphql). GraphQL exposes a single endpoint. The client describes exactly what it wants in the request body, rather than hitting many resource URLs.
In GraphQL, what is a 'query' used for?
- Defining the schema
- Creating new data
- Reading (fetching) data
- Deleting data
Answer: Reading (fetching) data. A query reads data. Operations that change data (create, update, delete) are mutations.
Which operation type changes data on the server?
- fragment
- mutation
- subscription
- query
Answer: mutation. Mutations create, update, or delete data. Queries are read-only by convention.
What is a resolver?
- A caching layer
- The HTTP router
- A database table
- A function that returns the value for a field
Answer: A function that returns the value for a field. Each field is backed by a resolver function that produces its value, often by reading a database or calling another service.
What problem does GraphQL solve compared to REST?
- Over-fetching and under-fetching of data
- It makes PHP run faster
- It removes the need for a database
- It encrypts traffic automatically
Answer: Over-fetching and under-fetching of data. REST endpoints return fixed shapes, causing over-fetching (too much) or under-fetching (needing multiple round trips). GraphQL lets the client request exactly the fields it needs.
Which PHP library is the de-facto core engine for building GraphQL servers?
- symfony/console
- webonyx/graphql-php
- phpunit/phpunit
- guzzlehttp/guzzle
Answer: webonyx/graphql-php. webonyx/graphql-php is the reference PHP implementation of the GraphQL spec, and most higher-level tools build on it.
Which package is the popular GraphQL solution specifically for Laravel?
- Eloquent
- Blade
- Horizon
- Lighthouse
Answer: Lighthouse. Lighthouse lets you build a GraphQL server in Laravel using a schema-first, directive-driven approach on top of webonyx/graphql-php.
What is the SDL in GraphQL?
- A database driver
- A query caching protocol
- The Schema Definition Language used to describe types and fields
- A PHP extension
Answer: The Schema Definition Language used to describe types and fields. The Schema Definition Language (SDL) is the typed, human-readable syntax for declaring object types, fields, queries, and mutations.
In the type 'type User { id: ID! name: String! }', what does the '!' mean?
- The field is private
- The field is non-nullable (required)
- The field is deprecated
- The field is a list
Answer: The field is non-nullable (required). A trailing ! marks a field as non-nullable: the server guarantees it will always return a value of that type.
Why is GraphQL strongly typed via its schema?
- So the schema documents the API and validates every query before execution
- To replace the need for HTTPS
- So clients can skip authentication
- To slow down responses
Answer: So the schema documents the API and validates every query before execution. The typed schema is a contract: it self-documents the API, powers tooling and autocompletion, and lets the server validate a query's shape before any resolver runs.