GraphQL API с PHP: пошаговый туториал на практике

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

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

Начать курс

GraphQL API с PHP: пошаговый туториал на практике

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

Почему GraphQL и PHP — отличная пара?

PHP остаётся одним из самых популярных языков для серверной разработки. С помощью библиотеки webonyx/graphql-php вы можете легко интегрировать GraphQL в любой проект — от простого блога до сложной CRM. Основные преимущества:

  • Гибкость запросов — клиент сам решает, какие поля получать.
  • Одна точка входа — вместо множества эндпоинтов один /graphql.
  • Строгая типизация — схема определяет все типы и связи.
  • Удобство для фронтенда — React, Vue и другие фреймворки легко работают с GraphQL.

Пошаговая реализация GraphQL API на PHP

1. Установка и настройка окружения

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

composer require webonyx/graphql-php

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

composer require guzzlehttp/psr7 nyholm/psr7-server

Создадим базовую структуру папок:

project/
├── src/
│   ├── Schema/
│   ├── Resolvers/
│   └── Types/
├── public/
│   └── index.php
├── vendor/
└── composer.json

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

Схема — это сердце GraphQL API. Она описывает типы данных и доступные операции. Создадим файл src/Schema/Schema.php:

<?php
namespace App\Schema;

use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Schema as GraphQLSchema;

class Schema
{
    public static function build(): GraphQLSchema
    {
        // Тип "User"
        $userType = new ObjectType([
            'name' => 'User',
            'fields' => [
                'id' => Type::int(),
                'name' => Type::string(),
                'email' => Type::string(),
            ]
        ]);

        // Тип "Query" — корневой запрос
        $queryType = new ObjectType([
            'name' => 'Query',
            'fields' => [
                'user' => [
                    'type' => $userType,
                    'args' => [
                        'id' => Type::nonNull(Type::int())
                    ],
                    'resolve' => function ($root, $args) {
                        // Здесь будет резолвер
                        return UserResolver::getUser($args['id']);
                    }
                ],
                'users' => [
                    'type' => Type::listOf($userType),
                    'resolve' => function () {
                        return UserResolver::getAllUsers();
                    }
                ]
            ]
        ]);

        // Тип "Mutation" — корневая мутация
        $mutationType = new ObjectType([
            'name' => 'Mutation',
            'fields' => [
                'createUser' => [
                    'type' => $userType,
                    'args' => [
                        'name' => Type::nonNull(Type::string()),
                        'email' => Type::nonNull(Type::string())
                    ],
                    'resolve' => function ($root, $args) {
                        return UserResolver::createUser($args['name'], $args['email']);
                    }
                ]
            ]
        ]);

        return new GraphQLSchema([
            'query' => $queryType,
            'mutation' => $mutationType
        ]);
    }
}

3. Реализация резолверов

Резолверы — это функции, которые возвращают данные для каждого поля. Создадим src/Resolvers/UserResolver.php:

<?php
namespace App\Resolvers;

class UserResolver
{
    private static $users = [
        1 => ['id' => 1, 'name' => 'Иван Петров', 'email' => 'ivan@example.com'],
        2 => ['id' => 2, 'name' => 'Мария Сидорова', 'email' => 'maria@example.com'],
    ];

    public static function getUser(int $id): ?array
    {
        return self::$users[$id] ?? null;
    }

    public static function getAllUsers(): array
    {
        return array_values(self::$users);
    }

    public static function createUser(string $name, string $email): array
    {
        $newId = count(self::$users) + 1;
        self::$users[$newId] = [
            'id' => $newId,
            'name' => $name,
            'email' => $email
        ];
        return self::$users[$newId];
    }
}

4. Точка входа — обработка запросов

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

<?php
require_once __DIR__ . '/../vendor/autoload.php';

use App\Schema\Schema;
use GraphQL\GraphQL;
use GraphQL\Error\Debug;
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7Server\ServerRequestCreator;

// Создаём PSR-7 запрос из глобальных переменных
$psr17Factory = new Psr17Factory();
$creator = new ServerRequestCreator(
    $psr17Factory,
    $psr17Factory,
    $psr17Factory,
    $psr17Factory
);
$request = $creator->fromGlobals();

// Получаем тело запроса
$body = json_decode((string)$request->getBody(), true);
$query = $body['query'] ?? '';
$variables = $body['variables'] ?? null;

// Строим схему и выполняем запрос
try {
    $schema = Schema::build();
    $result = GraphQL::executeQuery(
        $schema,
        $query,
        null,
        null,
        $variables
    );
    $output = $result->toArray(Debug::INCLUDE_DEBUG_MESSAGE);
} catch (\Exception $e) {
    $output = [
        'errors' => [
            ['message' => $e->getMessage()]
        ]
    ];
}

// Отправляем JSON-ответ
header('Content-Type: application/json');
echo json_encode($output);

Тестирование API

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

php -S localhost:8000 -t public/

Теперь можно отправлять запросы. Пример запроса через curl:

curl -X POST http://localhost:8000/ \
  -H "Content-Type: application/json" \
  -d '                

Блоги

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