Introduction to GraphQL and PHP
GraphQL is a query language for APIs and a runtime for executing those queries with existing data. Unlike REST, where you get a fixed response structure, GraphQL allows the client to request only the data it actually needs. This makes the API more flexible and efficient.
In this tutorial, we will create a simple GraphQL API in PHP from scratch. You will learn how to install the necessary libraries, define a schema, write resolvers, and handle queries. The article is intended for beginner developers familiar with the basics of PHP and databases (e.g., MySQL or SQLite).
We will use the webonyx/graphql-php library — the most popular and stable package for implementing GraphQL in PHP. By the end, you will be able to run your own GraphQL server and send queries to it via any HTTP client (e.g., cURL or Insomnia).
Project Installation and Setup
Step 1: Creating the Project and Installing Dependencies
First, create a new directory for the project and initialize Composer:
mkdir graphql-php-tutorialcd graphql-php-tutorialcomposer initThen install the webonyx/graphql-php library:
composer require webonyx/graphql-phpWe will also need a PSR-7 compatible HTTP server. For simplicity, we will use the built-in PHP server and the guzzlehttp/psr7 library for working with requests and responses:
composer require guzzlehttp/psr7Step 2: Project Structure
Create the following file structure:
index.php— application entry pointschema.graphql— file with the GraphQL schema definitionresolvers.php— file with resolver functionsdata.php— database simulation (array with data)
Defining the GraphQL Schema
Step 3: Writing the Schema
The schema is a description of data types and available operations (queries and mutations). Let's create a simple schema for managing a list of books. Open the schema.graphql file and paste the following code:
type Book { id: ID! title: String! author: String! year: Int}
type Query { books: [Book] book(id: ID!): Book}
type Mutation { addBook(title: String!, author: String!, year: Int): Book deleteBook(id: ID!): Book}Here we have defined:
- Book — a data type with fields id, title, author, and year.
- Query — operations for retrieving data: a list of all books and a book by ID.
- Mutation — operations for modifying data: adding and deleting a book.
Step 4: Preparing Data and Resolvers
Create the data.php file with an array of books:
<?php$books = [ 1 => ['id' => 1, 'title' => 'War and Peace', 'author' => 'Leo Tolstoy', 'year' => 1869], 2 => ['id' => 2, 'title' => 'Crime and Punishment', 'author' => 'Fyodor Dostoevsky', 'year' => 1866],];Now let's write the resolvers in the resolvers.php file. Resolvers are functions that return data for each schema field.
<?phprequire 'data.php';
function resolveBooks() { global $books; return array_values($books);}
function resolveBook($root, $args) { global $books; return $books[$args['id']] ?? null;}
function resolveAddBook($root, $args) { global $books; $newId = count($books) + 1; $newBook = [ 'id' => $newId, 'title' => $args['title'], 'author' => $args['author'], 'year' => $args['year'] ?? null ]; $books[$newId] = $newBook; return $newBook;}
function resolveDeleteBook($root, $args) { global $books;