Если вы PHP-разработчик и слышали про GraphQL, но не знали, с чего начать, эта статья для вас. Мы разберём, что такое GraphQL, зачем он нужен, и как его использовать в PHP. Без лишней теории — только практика и примеры.

Digital-студия WNDER

Что такое GraphQL и зачем он нужен PHP-разработчику

GraphQL — это язык запросов для API. Вместо того чтобы бегать по разным эндпоинтам REST (например, /users, /posts, /comments), вы отправляете один запрос и получаете ровно те данные, которые нужны. Ни больше, ни меньше.

Представьте, что вы в ресторане. Вместо того чтобы заказывать каждое блюдо отдельно (REST), вы говорите официанту: «Принесите мне стейк, картошку и салат, но без лука». GraphQL — это тот самый официант, который точно знает, что вам нужно.

Почему это важно для PHP? Потому что PHP часто используется для бэкенда, и если вы делаете API для мобильного приложения или SPA, GraphQL может сильно упростить жизнь. Клиент сам решает, какие поля ему нужны, и вы не тратите время на создание десятков эндпоинтов.

Установка и настройка GraphQL в PHP

Для работы с GraphQL в PHP есть несколько библиотек. Самая популярная — webonyx/graphql-php. Она реализует спецификацию GraphQL и предоставляет удобный API для создания схемы и резолверов.

Установим её через Composer:

composer require webonyx/graphql-php

Теперь создадим простой сервер. Допустим, у нас есть база данных с пользователями. Мы хотим отдавать их через GraphQL.

Сначала опишем схему. В GraphQL схема — это описание типов и запросов. Создадим файл schema.php:

<?php
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Schema;

// Определяем тип User
$userType = new ObjectType([
    'name' => 'User',
    'fields' => [
        'id' => Type::int(),
        'name' => Type::string(),
        'email' => Type::string(),
    ],
]);

// Определяем корневой запрос
$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'user' => [
            'type' => $userType,
            'args' => [
                'id' => Type::int(),
            ],
            'resolve' => function ($root, $args) {
                // Здесь обычно запрос к БД
                $users = [
                    1 => ['id' => 1, 'name' => 'Иван', 'email' => 'ivan@example.com'],
                    2 => ['id' => 2, 'name' => 'Мария', 'email' => 'maria@example.com'],
                ];
                return $users[$args['id']] ?? null;
            },
        ],
    ],
]);

// Создаём схему
$schema = new Schema([
    'query' => $queryType,
]);

Теперь создадим точку входа index.php, которая будет обрабатывать GraphQL-запросы:

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

use GraphQL\GraphQL;
use GraphQL\Error\DebugFlag;

// Получаем запрос от клиента
$input = json_decode(file_get_contents('php://input'), true);
$query = $input['query'] ?? '';
$variableValues = $input['variables'] ?? null;

// Выполняем
$result = GraphQL::executeQuery($schema, $query, null, null, $variableValues);
$output = $result->toArray();

// Отдаём JSON
header('Content-Type: application/json');
echo json_encode($output);

Всё, сервер готов. Теперь можно отправлять GraphQL-запросы, например, через curl:

curl -X POST http://localhost:8000/index.php \
  -H "Content-Type: application/json" \
  -d '{"query": "{ user(id: 1) { name email } }"}'

В ответ придёт JSON с данными пользователя.

Правило: Всегда валидируйте входящие GraphQL-запросы. Используйте встроенные механизмы библиотеки, чтобы избежать ошибок и атак.

Клиент на PHP: как отправлять GraphQL-запросы

PHP может не только принимать GraphQL-запросы, но и отправлять их. Например, если вы хотите получить данные из другого GraphQL API. Для этого можно использовать обычный curl или библиотеку guzzlehttp/guzzle.

Пример с Guzzle:

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

use GuzzleHttp\Client;

$client = new Client();
$query = '
    query ($id: Int!) {
        user(id: $id) {
            name
            email
        }
    }
';
$variables = ['id' => 1];

$response = $client->post('http://localhost:8000/index.php', [
    'json' => [
        'query' => $query,
        'variables' => $variables,
    ],
]);

$data = json_decode($response->getBody()->getContents(), true);
print_r($data);

Такой подход удобен, когда ваш PHP-бэкенд агрегирует данные из нескольких GraphQL-сервисов.

Сравнение GraphQL и REST: что выбрать для PHP-проекта

Давайте сравним два подхода в таблице, чтобы было наглядно.

Критерий REST GraphQL
Количество запросов Много (по одному на ресурс) Один запрос
Избыточность данных Часто передаёт лишние поля Только запрошенные поля
Гибкость Низкая (жёсткие эндпоинты) Высокая (клиент решает)
Кэширование Простое (HTTP-кэш) Сложнее (нужен клиентский кэш)
Порог входа Низкий Средний

GraphQL выигрывает, когда у вас сложные взаимосвязи между данными и много клиентов с разными потребностями. REST проще и лучше подходит для простых API.

Практические советы и лайфхаки

Вот несколько советов, которые сэкономят вам время и нервы при работе с GraphQL в PHP.

  • Используйте инструменты для отладки. Например, GraphiQL или Altair — они позволяют исследовать схему и тестировать запросы.
  • Разделяйте схему и резолверы. Не пихайте всё в один файл. Создайте отдельные классы для типов и логики.
  • Обрабатывайте ошибки. GraphQL возвращает ошибки в отдельном поле. Убедитесь, что ваш клиент умеет их читать.
  • Ограничивайте сложность запросов. Чтобы избежать DoS-атак, используйте анализ сложности запроса (query complexity).
Лайфхак: Если вы используете Laravel, обратите внимание на пакет rebing/graphql-laravel. Он сильно упрощает интеграцию.

Ещё один момент: не забывайте про безопасность. GraphQL позволяет клиенту запрашивать вложенные данные, поэтому нужно контролировать глубину запроса. В библиотеке webonyx есть настройка maxDepth.

Заключение

GraphQL — это мощный инструмент, который может сделать ваш PHP-бэкенд более гибким и удобным для клиентов. Да, порог входа немного выше, чем у REST, но потраченное время окупается. В PHP есть отличные библиотеки, такие как webonyx/graphql-php, которые берут на себя всю рутину.

Попробуйте перевести хотя бы один небольшой проект на GraphQL. Начните с простой схемы, поиграйтесь с запросами. Уверен, вам понравится.

Если у вас есть опыт с GraphQL в PHP, делитесь в комментариях. А если только начинаете — удачи, и не бойтесь экспериментировать.

Студия WNDER