GraphQL API с PHP: пошаговый туториал для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в GraphQL и PHP

GraphQL — это язык запросов для API и среда выполнения для выполнения этих запросов с существующими данными. В отличие от REST, где вы получаете фиксированную структуру ответа, GraphQL позволяет клиенту запрашивать только те данные, которые ему действительно нужны. Это делает API более гибким и эффективным.

В этом туториале мы создадим простой GraphQL API на PHP с нуля. Вы узнаете, как установить необходимые библиотеки, определить схему, написать резолверы и обработать запросы. Статья рассчитана на начинающих разработчиков, знакомых с основами PHP и базами данных (например, MySQL или SQLite).

Мы будем использовать библиотеку webonyx/graphql-php — это самый популярный и стабильный пакет для реализации GraphQL на PHP. В конце вы сможете запустить свой собственный GraphQL-сервер и выполнять к нему запросы через любой HTTP-клиент (например, cURL или Insomnia).

Установка и настройка проекта

Шаг 1: Создание проекта и установка зависимостей

Для начала создадим новую директорию для проекта и инициализируем Composer:

mkdir graphql-php-tutorial
cd graphql-php-tutorial
composer init

Затем установим библиотеку webonyx/graphql-php:

composer require webonyx/graphql-php

Также нам понадобится PSR-7 совместимый HTTP-сервер. Для простоты используем встроенный PHP-сервер и библиотеку guzzlehttp/psr7 для работы с запросами и ответами:

composer require guzzlehttp/psr7

Шаг 2: Структура проекта

Создайте следующую структуру файлов:

  • index.php — точка входа в приложение
  • schema.graphql — файл с определением схемы GraphQL
  • resolvers.php — файл с функциями-резолверами
  • data.php — имитация базы данных (массив с данными)

Определение схемы GraphQL

Шаг 3: Написание схемы

Схема — это описание типов данных и доступных операций (запросы и мутации). Создадим простую схему для управления списком книг. Откройте файл schema.graphql и вставьте следующий код:

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
}

Здесь мы определили:

  • Book — тип данных с полями id, title, author и year.
  • Query — операции для получения данных: список всех книг и книга по ID.
  • Mutation — операции для изменения данных: добавление и удаление книги.

Шаг 4: Подготовка данных и резолверов

Создайте файл data.php с массивом книг:

<?php
$books = [
    1 => ['id' => 1, 'title' => 'Война и мир', 'author' => 'Лев Толстой', 'year' => 1869],
    2 => ['id' => 2, 'title' => 'Преступление и наказание', 'author' => 'Фёдор Достоевский', 'year' => 1866],
];

Теперь напишем резолверы в файле resolvers.php. Резолверы — это функции, которые возвращают данные для каждого поля схемы.

<?php
require '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;
    $book = $books[$args['id']] ?? null;
    if ($book) {
        unset($books[$args['id']]);
    }
    return $book;
}

Объединение схемы и резолверов в сервере

Шаг 5: Создание точки входа (index.php)

Теперь соединим всё вместе. В файле index.php мы создадим GraphQL-сервер, который будет принимать HTTP-запросы, обрабатывать их и возвращать ответы.

<?php
require 'vendor/autoload.php';
require 'resolvers.php';

use GraphQL\GraphQL;
use GraphQL\Utils\BuildSchema;
use Psr\Http\Message\ServerRequestInterface;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\ServerRequest;

// Загружаем схему из файла
$schemaContent = file_get_contents('schema.graphql');
$schema = BuildSchema::build($schemaContent);

// Создаем маппинг резолверов
$rootValue = [
    'books' => 'resolveBooks',
    'book' => 'resolveBook',
    'addBook' => 'resolveAddBook',
    'deleteBook' => 'resolveDeleteBook',
];

// Обрабатываем входящий запрос
$request = ServerRequest::fromGlobals();
$body = (string) $request->getBody();
$input = json_decode($body, true);
$query = $input['query'];
$variables = $input['variables'] ?? null;

try {
    // Выполняем запрос
    $result = GraphQL::executeQuery(
        $schema,
        $query,
        $rootValue,
        null,
        $variables
    );
    $output = $result->toArray();
} catch (\Exception $e) {
    $output = ['errors' => [['message' => $e->getMessage()]]];
}

// Отправляем ответ
$response = new Response(200, ['Content-Type' => 'application/json'], json_encode($output));
// В реальном приложении здесь нужно отправить response через эмиттер PSR-7
echo $response->getBody();

Шаг 6: Запуск и тестирование

Запустите встроенный PHP-сервер:

php -S localhost:8000 index.php

Теперь вы можете отправлять GraphQL-

Блоги

Рекомендаций по книгам