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

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

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

Начать курс

Введение в GraphQL с PHP: почему это стоит попробовать

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

В этом туториале мы создадим полноценный GraphQL API на PHP с использованием библиотеки webonyx/graphql-php. Вы узнаете, как определить схему, написать резолверы, обработать запросы и мутации, а также протестировать API через GraphiQL.

Предполагается, что у вас установлен PHP 8.0+ и Composer. Если нет — начните с их установки.

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

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

Создайте новую директорию для проекта и инициализируйте Composer:

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

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

composer require webonyx/graphql-php

Также установите nikic/fast-route для простой маршрутизации (опционально, но удобно):

composer require nikic/fast-route

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

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

graphql-php-tutorial/
├── src/
│   ├── Schema/
│   │   └── schema.php
│   ├── Resolvers/
│   │   ├── QueryResolver.php
│   │   └── MutationResolver.php
│   └── Data/
│       └── Database.php
├── public/
│   └── index.php
├── vendor/
└── composer.json

Создание схемы GraphQL

Шаг 3: Определение типов и схемы

Создадим простую модель данных: пользователь (User) и пост (Post). Откройте 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(),
                'posts' => [
                    'type' => Type::listOf(function() use (&$postType) {
                        return $postType;
                    }),
                    'resolve' => function($user) {
                        return \App\Resolvers\QueryResolver::getPostsByUser($user['id']);
                    }
                ]
            ]
        ]);

        // Тип Post
        $postType = new ObjectType([
            'name' => 'Post',
            'fields' => [
                'id' => Type::int(),
                'title' => Type::string(),
                'content' => Type::string(),
                'author' => [
                    'type' => $userType,
                    'resolve' => function($post) {
                        return \App\Resolvers\QueryResolver::getUserById($post['author_id']);
                    }
                ]
            ]
        ]);

        // Корневой тип Query
        $queryType = new ObjectType([
            'name' => 'Query',
            'fields' => [
                'users' => [
                    'type' => Type::listOf($userType),
                    'resolve' => function() {
                        return \App\Resolvers\QueryResolver::getAllUsers();
                    }
                ],
                'user' => [
                    'type' => $userType,
                    'args' => [
                        'id' => Type::nonNull(Type::int())
                    ],
                    'resolve' => function($root, $args) {
                        return \App\Resolvers\QueryResolver::getUserById($args['id']);
                    }
                ],
                'posts' => [
                    'type' => Type::listOf($postType),
                    'resolve' => function() {
                        return \App\Resolvers\QueryResolver::getAllPosts();
                    }
                ]
            ]
        ]);

        // Корневой тип 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 \App\Resolvers\MutationResolver::createUser($args);
                    }
                ],
                'createPost' => [
                    'type' => $postType,
                    'args' => [
                        'title' => Type::nonNull(Type::string()),
                        'content' => Type::nonNull(Type::string()),
                        'author_id' => Type::nonNull(Type::int())
                    ],
                    'resolve' => function($root, $args) {
                        return \App\Resolvers\MutationResolver::createPost($args);
                    }
                ]
            ]
        ]);

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

Реализация резолверов и базы данных

Шаг 4: Создание резолверов для запросов

Файл src/Resolvers/QueryResolver.php:

<?php

namespace App\Resolvers;

use App\Data\Database;

class QueryResolver
{
    public static function getAllUsers(): array
    {
        return Database::getUsers();
    }

    public static function getUserById(int $id): ?array
    {
        $users = Database::getUsers();
        foreach ($users as $user) {
            if ($user['id'] === $id) {
                return $user;
            }
        }
        return null;
    }

    public static function getAllPosts(): array
    {
        return Database::getPosts();
    }

    public static function getPostsByUser(int $userId): array
    {
        $posts = Database::getPosts();
        return array_filter($posts, function($post) use ($userId) {
            return $post['author_id'] === $userId;
        });
    }
}

Шаг 5: Создание резолверов для мутаций

Файл src/Resolvers/MutationResolver.php:

<?php

namespace App\                

Блоги

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