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.