Пример создания GraphQL API на Laravel. Часть 1

В одной из предыдущих статей мы разобрались, что такое GraphQL в теории. Сегодня рассмотрим пример создания GraphQL API на Laravel.

Установка библиотеки Graphql

Для создания API воспользуемся пакетом folklore/graphql, который является оберткой пакета webonyx/graphql-php (самой популярной реализации GraphQL для PHP) для использования в Laravel. Установим его через Composer:

composer require folklore/graphql

Если вы используете Laravel 5.5 или выше, то фреймворк настроит пакет автоматически, нужно только опубликовать конфигурационный файл с помощью команды:

php artisan vendor:publish --provider="Folklore\GraphQL\ServiceProvider"

Это создаст новый файл конфигурации config/graphql.php.

Если вы используете Laravel 5.4 или ниже, то для настройки пакета нужно выполнить следующие шаги:

  1. Добавить новый сервис провайдер в config/app.php:
    Folklore\GraphQL\ServiceProvider::class,
  2. Добавить новый фасад в config/app.php:
    GraphQL' => Folklore\GraphQL\Support\Facades\GraphQL::class,
  3. Опубликовать файл конфигурации для пакета:
    php artisan vendor:publish --provider="Folklore\GraphQL\ServiceProvider"

После установки в браузере по адресу /graphiql должен быть доступен графический интерфейс для выполнения запросов GraphQL:

Интерфейс Graphiql

Пример API

Создадим простой API для создания и получения информации о пользователях. Laravel по умолчанию имеет модель User и миграцию для создания соответствующей таблицы в базе данных.

Для начала создадим новый тип User, запрос UsersQuery для получения данных о пользователе и мутацию CreateUserMutation для создания новых пользователей:

php artisan make:graphql:type UserType
php artisan make:graphql:query UsersQuery
php artisan make:graphql:mutation CreateUserMutation

Ниже приведен код для созданных классов:

GraphQL/Type/UserType.php:

<?php

namespace App\GraphQL\Type;

use Folklore\GraphQL\Support\Type as BaseType;
use GraphQL\Type\Definition\Type;

class UserType extends BaseType
{
    protected $attributes = [
        'name' => 'UserType',
        'description' => 'A type'
    ];

    public function fields()
    {
        return [
            'id' => [
                'type' => Type::nonNull(Type::int()),
                'description' => 'The id of the user'
            ],
            'email' => [
                'type' => Type::string(),
                'description' => 'The email of user'
            ],
            'name' => [
                'type' => Type::string(),
                'description' => 'The name of user'
            ]
        ];
    }
}

GraphQL/Query/UsersQuery.php:

<?php

namespace App\GraphQL\Query;

use App\User;
use Folklore\GraphQL\Support\Query;
use GraphQL;
use GraphQL\Type\Definition\Type;

class UsersQuery extends Query
{
    protected $attributes = [
        'name' => 'UsersQuery',
        'description' => 'A query'
    ];

    public function type()
    {
        return Type::listOf(GraphQL::type('User'));
    }

    public function args()
    {
        return [
            'id' => ['name' => 'id', 'type' => Type::int()],
            'email' => ['name' => 'email', 'type' => Type::string()]
        ];
    }

    public function resolve($root, $args)
    {
        if (isset($args['id'])) {
            return User::where('id' , $args['id'])->get();
        } else if(isset($args['email'])) {
            return User::where('email', $args['email'])->get();
        } else {
            return User::all();
        }
    }
}

Данный класс используется для получения данных о пользователях. При этом в запрос может передаваться id или email пользователя, для которого мы хотим получить данные.

GraphQL/Mutation/CreateUserMutation.php:

<?php

namespace App\GraphQL\Mutation;

use App\User;
use Folklore\GraphQL\Support\Mutation;
use GraphQL;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type;

class CreateUserMutation extends Mutation
{
    protected $attributes = [
        'name' => 'createUser',
        'description' => 'A mutation'
    ];

    public function type()
    {
        return GraphQL::type('User');
    }

    public function args()
    {
        return [
            'name' => [
                'type' => Type::nonNull(Type::string())
            ],
            'email' => [
                'type' => Type::nonNull(Type::string()),
                'rules' => ['email', 'unique:users']
            ],
            'password' => [
                'type' => Type::nonNull(Type::string()),
                'rules' => ['min:4']
            ]
        ];
    }

    public function resolve($root, $args, $context, ResolveInfo $info)
    {
        $user = new User();
        $user->fill($args);
        $user->save();
        return $user;
    }
}

Мутация для создания пользователя принимает на вход имя, email и пароль, и возвращает в ответ информацию о созданном пользователе. Так же для каждого поля могут быть заданы правила валидации, которые используют стандартную валидацию Laravel.

После этого нужно добавить созданные сущности в файл config/graphql.php:

'schemas' => [
    'default' => [
        'query' => [
            'users' => 'App\GraphQL\Query\UsersQuery'
        ],
        'mutation' => [
            'createUser' => 'App\GraphQL\Mutation\CreateUserMutation'
        ]
    ]
],
'types' => [
 'User' => 'App\GraphQL\Type\UserType'
],

Если теперь открыть адрес /graphiql в браузере, вы увидите, что вкладка Docs отображает документацию по только что созданному API. На скриншоте ниже видно, как выглядит результат выполнения запроса на создание нового пользователя и документации по мутации createUser, которая была использована в этом запросе.

Отображение мутации в Graphiql

Теперь создадим первый запрос на создание пользователя:

mutation {
  createUser(
    name: "Test User",
    email:"test@example.com",
    password:"qwerty"
  ) {
    id,
    email,
    name
  }
}

Если все настроено правильно, то сервер вернет следующий ответ:

{
  "data": {
    "createUser": {
      "id": 1,
      "email": "test@example.com",
      "name": "Test User"
    }
  }
}

Получим данные только что созданного пользователя:

query {
  users (id: 1) {
    id
    email
  }
}

Сервер вернет следующий ответ:

{
  "data": {
    "users": [
      {
        "id": 1,
        "email": "test@example.com"
      }
    ]
  }
}

Как видно, сервер возвращает только те поля пользователя, которые указаны в запросе, что очень удобно и позволяет ускорить выполнение запроса, когда требуется получить только несколько полей для каждой записи. В данном примере мы использовали фильтрацию пользователей по id. Если не передавать в запрос никаких параметров, то API вернет массив всех пользователей.

Заключение

В данной статье мы рассмотрели пример создания GraphQL API на Laravel.

Для запуска API из этой статьи вы можете скачать код с GitHub по ссылке https://github.com/RusinovIG/blog-examples/tree/graphql-example и запустить локально.

Используемый пакет позволяет очень гибко настраивать правила для создания, обновления и получения данных на сервере, при этом, благодаря спецификациям GraphQL, мы получаем самодокументируемый API, что наглядно демонстрируется в примере с помощью встроенной в пакет графической IDE для работы с GraphQL-запросами.

О более сложных примерах использования GraphQL читайте во второй части статьи.

Пример создания GraphQL API на Laravel. Часть 1: 4 комментария

    1. На этой неделе выйдет продолжение с более сложными примерами. Подписывайтесь на обновления, чтобы не пропустить)

  1. Уведомление: GraphQL — iTelmenko

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.