Создание сервера GraphQL с помощью Laravel
Опубликовано: 2022-03-11Если вы еще не знакомы с ним, GraphQL — это язык запросов, используемый для взаимодействия с вашим API, который дает некоторые преимущества по сравнению с альтернативными архитектурами, такими как REST. GraphQL чрезвычайно удобен при использовании в качестве конечной точки для мобильных и одностраничных приложений. GraphQL позволяет относительно легко запрашивать вложенные и связанные данные в запросе, позволяя разработчикам получать точные данные, которые им нужны, за одно обращение к серверу.
Laravel — это популярный веб-фреймворк на PHP. Он предоставляет множество встроенных инструментов для быстрого запуска и запуска приложений, но также позволяет разработчикам заменять свои собственные реализации встроенными интерфейсами Laravel, когда это необходимо.
Хотя сообщества, окружающие как GraphQL, так и Laravel, резко выросли с тех пор, как они стали открытыми, документации, объясняющей, как использовать эти две технологии вместе, все еще немного мало.
Итак, в этом уроке я покажу вам, как создать свой собственный сервер GraphQL с помощью Laravel.
Обзор проекта
Прежде чем мы начнем, нам нужно ознакомиться с проектом, который мы пытаемся создать. Для этого мы определим наши ресурсы и создадим нашу схему GraphQL, которую мы позже будем использовать для обслуживания нашего API.
Ресурсы проекта
Наше приложение будет состоять из двух ресурсов: Articles и Users . Эти ресурсы будут определены как типы объектов в нашей схеме GraphQL:
type User { id: ID! name: String! email: String! articles: [Article!]! } type Article { id: ID! title: String! content: String! author: User! }
Глядя на схему, мы видим, что у нас есть отношение «один ко многим» между нашими двумя объектами. Пользователи могут писать много статей, и у статьи есть назначенный автор (пользователь).
Теперь, когда у нас определены типы объектов, нам понадобится способ создания и запроса наших данных, поэтому давайте определим наши объекты запроса и мутации:
type Query { user(id: ID!): User users: [User!]! article(id: ID!): Article articles: [Article!]! } type Mutation { createUser(name: String!, email: String!, password: String!): User createArticle(title: String!, content: String!): Article }
Настройка нашего проекта Laravel
Теперь, когда мы определили нашу схему GraphQL, давайте запустим наш проект Laravel. Начнем с создания нового проекта Laravel через Composer:
$ composer create-project --prefer-dist laravel/laravel laravel-graphql
Просто чтобы убедиться, что у нас все работает, давайте загрузим наш сервер и убедимся, что мы видим страницу Laravel по умолчанию:
$ cd laravel-graphql $ php artisan serve Laravel development server started: <http://127.0.0.1:8000>
Модели баз данных и миграции
Для целей этой статьи мы будем использовать SQLite. Итак, давайте внесем следующие изменения в файл .env
по умолчанию:
DB_CONNECTION=sqlite # DB_HOST= # DB_PORT= # DB_DATABASE=database.sqlite # DB_USERNAME= # DB_PASSWORD=
Далее создадим файл нашей базы данных:
$ touch ./database/database.sqlite
Laravel поставляется с пользовательской моделью и некоторыми базовыми файлами миграции. Давайте быстро добавим столбец api_token
в наш файл миграции CreateUsersTable
, предоставленный нам Laravel:
/database/migrations/XXXX_XX_XX_000000_create_users_table.php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersTable extends Migration { /** * Run the migrations. */ public function up() { Schema::create('users', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->string('api_token', 80)->unique()->nullable()->default(null); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down() { Schema::dropIfExists('users'); } }
Мы вернемся к этому дополнительному столбцу позже в статье, когда дойдем до авторизации. Теперь давайте продолжим и создадим нашу модель статьи и файл миграции для создания связанной таблицы:
$ php artisan make:model Article -m
Примечание. Параметр -m создает файл миграции для вновь созданной модели статьи.
Внесем некоторые коррективы в сгенерированный файл миграции:
use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateArticlesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('articles', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('user_id'); $table->string('title'); $table->text('content'); $table->timestamps(); $table->foreign('user_id')->references('id')->on('users'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('articles'); } }
Мы добавили внешний ключ, указывающий на id
в нашей таблице users
, а также на столбцы title
и content
, которые мы определили в нашей схеме GraphQL.
Теперь, когда мы определили наши файлы миграции, давайте продолжим и запустим их в нашей базе данных:
$ php artisan migrate
Далее давайте обновим наши модели, определив необходимые отношения:
app/User.php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', ]; // ... /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function articles() { return $this->hasMany(Article::class); } }
app/Article.php namespace App; use Illuminate\Database\Eloquent\Model; class Article extends Model { /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'title', 'content', ]; /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() { return $this->belongsTo(User::class); } }
Заполнение базы данных
Теперь, когда у нас настроены модели и миграции, давайте запустим нашу базу данных. Мы начнем с создания некоторых классов сидов для наших articles
и таблиц users
:
$ php artisan make:seeder UsersTableSeeder $ php artisan make:seeder ArticlesTableSeeder
Затем давайте настроим их для вставки некоторых фиктивных данных в нашу базу данных SQLite:
database/seeds/UsersTableSeeder.php use App\User; use Illuminate\Database\Seeder; class UsersTableSeeder extends Seeder { /** * Run the database seeds. */ public function run() { \App\User::truncate(); $faker = \Faker\Factory::create(); $password = bcrypt('secret'); \App\User::create([ 'name' => $faker->name, 'email' => '[email protected]', 'password' => $password, ]); for ($i = 0; $i < 10; ++$i) { \App\User::create([ 'name' => $faker->name, 'email' => $faker->email, 'password' => $password, ]); } } }
database/seeds/ArticlesTableSeeder.php use App\Article; use Illuminate\Database\Seeder; class ArticlesTableSeeder extends Seeder { /** * Run the database seeds. */ public function run() { \App\Article::truncate(); \App\Article::unguard(); $faker = \Faker\Factory::create(); \App\User::all()->each(function ($user) use ($faker) { foreach (range(1, 5) as $i) { \App\Article::create([ 'user_id' => $user->id, 'title' => $faker->sentence, 'content' => $faker->paragraphs(3, true), ]); } }); } }
/database/seeds/DatabaseSeeder.php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { $this->call(UsersTableSeeder::class); $this->call(ArticlesTableSeeder::class); } }
Наконец, давайте продолжим и запустим наши сидеры базы данных, чтобы получить некоторые данные в нашу базу данных:
$ php artisan db:seed
Laravel Lighthouse и сервер GraphQL
Теперь, когда мы настроили нашу базу данных и модели, пришло время приступить к созданию нашего сервера GraphQL. В настоящее время для Laravel доступно несколько решений, но в этой статье мы будем использовать Lighthouse.
Lighthouse — это пакет, который я создал несколько лет назад и недавно получил потрясающую поддержку со стороны растущего сообщества вокруг него. Он позволяет разработчикам быстро настроить сервер GraphQL с использованием Laravel с небольшим шаблоном, а также достаточно гибок, чтобы позволить разработчикам настраивать его в соответствии с потребностями практически любого проекта.
Начнем с добавления пакета в наш проект:
$ composer require nuwave/lighthouse:"3.1.*"
Далее давайте опубликуем файл конфигурации Lighthouse:
$ php artisan vendor:publish --provider="Nuwave\Lighthouse\LighthouseServiceProvider" --tag=config
Примечание. Вы также можете опубликовать файл схемы Lighthouse по умолчанию, просто удалив параметр --tag=config
. Но для целей этой статьи мы собираемся создать наш файл схемы с нуля.
Если мы посмотрим на файл config/lighthouse.php
, вы заметите параметр, используемый для регистрации нашего файла схемы в Lighthouse:
'schema' => [ 'register' => base_path('graphql/schema.graphql'), ],
Итак, давайте продолжим и создадим наш файл схемы и настроим тип нашего пользовательского объекта и запрос:
$ mkdir graphql $ touch ./graphql/schema.graphql /graphql/schema.graphql type User { id: ID! name: String! email: String! } type Query { user(id: ID! @eq): User @find users: [User!]! @all }
Вы заметите, что наша схема похожа на ту, которую мы определили ранее, за исключением того, что мы добавили некоторые идентификаторы, называемые директивами схемы.
Давайте на минутку разберем нашу определенную схему. Наше первое определение — это тип объекта с именем User
, который имеет отношение к нашей красноречивой модели App\User
. Мы определили id
, name
и email
как поля, которые можно запрашивать из наших моделей User
. В качестве альтернативы это означает, что столбцы password
, created_at
и updated_at
являются полями, которые нельзя запрашивать из нашего API.
Далее у нас есть тип Query
, который является точкой входа в наш API и может использоваться для запроса данных. Наше первое поле — это поле users
которое возвращает массив типов объектов User
. Директива @all
указывает Lighthouse выполнить запрос Eloquent, используя нашу модель User
, и получить все результаты. Это было бы так же, как выполнение следующего:
$users = \App\User::all();
Примечание. Lighthouse знает, что модель следует искать в пространстве имен \App\User
, поскольку параметр namespaces
определен в его файле конфигурации.
Вторым определенным полем в нашем типе запроса является call user
, который принимает id
в качестве аргумента и возвращает один тип объекта User
. Мы также добавили две директивы, чтобы помочь Lighthouse автоматически построить для нас запрос и вернуть единую модель User
. Директива @eq
указывает Lighthouse добавить в столбец id
место, а директива @find
указывает Lighthouse вернуть один результат. Чтобы написать этот запрос с помощью построителя запросов Laravel, он будет выглядеть так:
$user = \App\User::where('id', $args['id'])->first();
Запрос нашего GraphQL API
Теперь, когда у нас есть некоторое представление о том, как Lighthouse использует нашу схему для создания запросов, давайте запустим наш сервер и начнем запрашивать данные. Начнем с запуска нашего сервера:
$ php artisan serve Laravel development server started: <http://127.0.0.1:8000>
Чтобы запросить конечную точку GraphQL, вы можете запустить команду cURL в терминале или стандартном клиенте, таком как Postman. Однако, чтобы получить все преимущества GraphQL (такие как автозаполнение, выделение ошибок, документация и т. д.), мы будем использовать GraphQL Playground (выпуск загрузок здесь).
При запуске Playground щелкните вкладку «URL Endpoint» и введите http://localhost:8000/graphql, чтобы указать GraphQL Playground на наш сервер. В левой части редактора мы можем запросить наши данные, поэтому давайте начнем с запроса всех пользователей, которыми мы заполнили базу данных:
{ users { id email name } }
Когда вы нажмете кнопку воспроизведения в середине IDE (или нажмите Ctrl+Enter ), вы увидите вывод JSON нашего сервера с правой стороны, который будет выглядеть примерно так:
{ "data": { "users": [ { "id": "1", "email": "[email protected]", "name": "Carolyn Powlowski" }, { "id": "2", "email": "[email protected]", "name": "Elouise Raynor" }, { "id": "3", "email": "[email protected]", "name": "Mrs. Dejah Wiza" }, ... ] } }
Примечание. Поскольку мы использовали Faker для заполнения нашей базы данных, данные в полях email
и name
будут другими.
Теперь давайте попробуем запросить для одного пользователя:
{ user(id: 1) { email name } }
И мы получим следующий вывод для одного пользователя:
{ "data": { "user": { "email": "[email protected]", "name": "Carolyn Powlowski" } } }
Запросы данных, подобные этому, хороши для начала, но очень маловероятно, что вы будете в проекте, где вам когда-либо понадобится запрашивать все ваши данные, поэтому давайте попробуем добавить немного разбиения на страницы. При просмотре широкого спектра встроенных директив Lighthouse у нас есть доступная директива @paginate
, поэтому давайте обновим объект запроса нашей схемы следующим образом:
type Query { user(id: ID! @eq): User @find users: [User!]! @paginate }
Если мы перезагрузим GraphQL Playground ( Ctrl/Cmd + R ) и повторим запрос наших users
, вы заметите, что мы получим сообщение об ошибке, в котором говорится, что не удается Cannot query field "id" on type "UserPaginator"
, так что же произошло? За кулисами Lighthouse манипулирует нашей схемой, чтобы мы могли получить разбитый на страницы набор результатов, и делает это, изменяя тип возвращаемого значения поля users
.

Давайте подробнее рассмотрим нашу схему на вкладке «Документы» GraphQL Playground. Если вы посмотрите на поле users
, оно возвращает UserPaginator
, который возвращает массив пользователей и определенный в Lighthouse тип PaginatorInfo
:
type UserPaginator { paginatorInfo: PaginatorInfo! data: [User!]! } type PaginatorInfo { count: Int! currentPage: Int! firstItem: Int hasMorePages: Boolean! lastItem: Int lastPage: Int! perPage: Int! total: Int! }
Если вы знакомы со встроенной пагинацией Laravel, поля, доступные в типе PaginatorInfo
, вероятно, покажутся вам очень знакомыми. Таким образом, чтобы запросить двух пользователей, получить общее количество пользователей в системе и убедиться, что у нас есть еще страницы для циклического просмотра, мы должны отправить следующий запрос:
{ users(count:2) { paginatorInfo { total hasMorePages } data { id name email } } }
Что даст нам следующий ответ:
{ "data": { "users": { "paginatorInfo": { "total": 11, "hasMorePages": true }, "data": [ { "id": "1", "name": "Carolyn Powlowski", "email": "[email protected]" }, { "id": "2", "name": "Elouise Raynor", "email": "[email protected]" }, ] } } }
Отношения
Как правило, при разработке приложения большая часть ваших данных связана. В нашем случае User
может написать много Articles
, поэтому давайте добавим это отношение к нашему типу пользователя и определим наш тип Article
:
type User { id: ID! name: String! email: String! articles: [Article!]! @hasMany } type Article { id: ID! title: String! content: String! }
Здесь мы используем другую директиву схемы, предоставленную Lighthouse @hasMany
, которая сообщает Lighthouse, что наша модель User
имеет \Illuminate\Database\Eloquent\Relations\HasMany
с моделью Article
.
Теперь давайте запросим наше новое отношение:
{ user(id:1) { articles { id title } } }
Это даст нам следующий ответ:
{ "data": { "user": { "articles": [ { "id": "1", "title": "Aut velit et temporibus ut et tempora sint." }, { "id": "2", "title": "Voluptatem sed labore ea voluptas." }, { "id": "3", "title": "Beatae sit et maxime consequatur et natus totam." }, { "id": "4", "title": "Corrupti beatae cumque accusamus." }, { "id": "5", "title": "Aperiam quidem sit esse rem sed cupiditate." } ] } } }
Наконец, давайте реверсируем нашу связь и добавим нашу связь author
к нашему типу объекта Article
, используя директиву схемы Lighthouse @belongsTo
, а также обновив наш Query
:
type Article { id: ID! title: String! content: String! author: User! @belongsTo(relation: "user") } type Query { user(id: ID! @eq): User @find users: [User!]! @paginate article(id: ID! @eq): Article @find articles: [Article!]! @paginate }
Вы увидите, что мы добавили необязательный аргумент relation
к директиве @belongsTo
. Это говорит Lighthouse использовать user
отношения модели « Articles
» и назначить их полю author
.
Теперь давайте запросим список статей и возьмем связанного с ними автора:
{ articles(count:2) { paginatorInfo { total hasMorePages } data { id title author { name email } } } }
И мы должны получить следующее от нашего сервера:
{ "data": { "articles": { "paginatorInfo": { "total": 55, "hasMorePages": true }, "data": [ { "id": "1", "title": "Aut velit et temporibus ut et tempora sint.", "author": { "name": "Carolyn Powlowski", "email": "[email protected]" } }, { "id": "2", "title": "Voluptatem sed labore ea voluptas.", "author": { "name": "Carolyn Powlowski", "email": "[email protected]" } } ] } } }
Мутация GraphQL
Теперь, когда мы можем запрашивать наши данные, давайте создадим некоторые мутации, чтобы создать новых пользователей и статьи. Начнем с нашей пользовательской модели:
type Mutation { createUser( name: String! email: String! @rules(apply: ["email", "unique:users"]) password: String! @bcrypt @rules(apply: ["min:6"]) ): User @create }
Теперь давайте разберем это определение схемы. Мы создали мутацию под названием createUser
, которая принимает три аргумента ( name
, email
и password
). Мы применили директиву @rules
к нашим аргументам email
и password
. Это может показаться немного знакомым, поскольку похоже на логику проверки, которую Laravel предоставляет для своих контроллеров.
Затем мы прикрепили директиву @bcrypt
к нашему полю password
. Это зашифрует пароль, прежде чем он будет передан во вновь созданную модель.
Наконец, чтобы помочь нам создавать новые модели, Lighthouse предоставляет директиву схемы @create
, которая примет определенные нами аргументы и создаст новую модель. Выполнение той же логики в контроллере будет выглядеть следующим образом:
namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { /** * Create a new user. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $data = $this->validate($request, [ 'email' => ['email', 'unique:users'], 'password' => ['min:6'] ]); $user = \App\User::create($data); return response()->json(['user' => $user]); } }
Теперь, когда у нас настроено поле мутации createUser, давайте продолжим и запустим его в GraphQL Playground со следующим:
mutation { createUser( name:"John Doe" email:"[email protected]" password: "secret" ) { id name email } }
Мы должны получить следующий вывод:
{ "data": { "createUser": { "id": "12", "name": "John Doe", "email": "[email protected]" } } }
Аутентификация и авторизация GraphQL
Поскольку нам нужно добавить user_id
в наши модели Article
, самое время перейти к аутентификации и авторизации в GraphQL/Lighthouse.
Чтобы аутентифицировать пользователя, нам нужно предоставить ему api_token
, поэтому давайте создадим мутацию для обработки этого и добавим директиву @field
, чтобы указать Lighthouse на пользовательский преобразователь, который будет обрабатывать логику. Мы устанавливаем распознаватель по тому же шаблону, что и при определении контроллера в Laravel, используя аргумент resolver
.
С помощью директивы @field
, определенной ниже, мы сообщаем Lighthouse, что при запуске мутации login
в систему используйте метод createToken
в нашем App\GraphQL\Mutations\AuthMutator
:
type Mutation { # ... login( email: String! password: String! ): String @field(resolver: "AuthMutator@resolve") }
Примечание. Вам не нужно включать сюда все пространство имен. В файле конфигурации lighthouse.php
вы увидите, что пространство имен, определенное для наших мутаций, уже установлено как App\\GraphQL\\Mutations
, однако вы можете использовать полное пространство имен, если хотите.
Давайте используем генератор Lighthouse для создания нового класса мутатора:
$ php artisan lighthouse:mutation AuthMutator
Далее давайте обновим нашу функцию-преобразователь следующим образом:
namespace App\GraphQL\Mutations; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Support\Facades\Auth; use GraphQL\Type\Definition\ResolveInfo; use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; class AuthMutator { /** * Return a value for the field. * * @param null $rootValue Usually contains the result returned from the parent field. In this case, it is always `null`. * @param mixed[] $args The arguments that were passed into the field. * @param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context Arbitrary data that is shared between all fields of a single query. * @param \GraphQL\Type\Definition\ResolveInfo $resolveInfo Information about the query itself, such as the execution state, the field name, path to the field from the root, and more. * @return mixed */ public function resolve($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) { $credentials = Arr::only($args, ['email', 'password']); if (Auth::once($credentials)) { $token = Str::random(60); $user = auth()->user(); $user->api_token = $token; $user->save(); return $token; } return null; } }
Теперь, когда у нас настроен преобразователь, давайте протестируем его и попробуем получить токен API, используя следующую мутацию в GraphQL Playground:
mutation { login(email:"[email protected]", password:"secret") }
Мы должны получить токен, отправленный нам обратно, например:
{ "data": { "login": "VJCz1DCpmdvB9WatqvWbXBP2RN8geZQlrQatUnWIBJCdbAyTl3UsdOuio3VE" } }
Примечание. Обязательно скопируйте токен, возвращенный в результате изменения входа в систему, чтобы мы могли использовать его позже.
Затем давайте добавим поле запроса, которое будет возвращать аутентифицированного пользователя, чтобы убедиться, что наша логика работает. Мы добавим поле с именем me
и используем директиву Lighthouse @auth
для возврата текущего аутентифицированного пользователя. Мы также установим аргумент guard
равным api
, поскольку именно так мы будем аутентифицировать пользователя.
type Query { # ... me: User @auth(guard: "api") }
Теперь запустим запрос. В GraphQL Playground вы можете установить заголовки запросов, дважды щелкнув вкладку «Http Headers» внизу. Мы добавляем заголовки с объектом JSON, поэтому, чтобы добавить токен носителя к каждому запросу, вы должны добавить следующее:
{ "Authorization": "Bearer VJCz1DCpmdvB9WatqvWbXBP2RN8geZQlrQatUnWIBJCdbAyTl3UsdOuio3VE" }
Примечание. Замените токен носителя на токен, который вы получили при выполнении запроса на вход .
Теперь запустим me
-запрос:
{ me { email articles { id title } } }
Мы должны получить вывод, который выглядит следующим образом:
{ "data": { "me": { "email": "[email protected]", "articles": [ { "id": "1", "title": "Rerum perspiciatis et quos occaecati exercitationem." }, { "id": "2", "title": "Placeat quia cumque laudantium optio voluptatem sed qui." }, { "id": "3", "title": "Optio voluptatem et itaque sit animi." }, { "id": "4", "title": "Excepturi in ad qui dolor ad perspiciatis adipisci." }, { "id": "5", "title": "Qui nemo blanditiis sed fugit consequatur." } ] } } }
ПО промежуточного слоя
Теперь, когда мы знаем, что наша аутентификация работает правильно, давайте создадим нашу последнюю мутацию для создания статьи с использованием текущего аутентифицированного пользователя. Мы будем использовать директиву @field
, чтобы указать Lighthouse на наш преобразователь, и мы также включим директиву @middleware
, чтобы убедиться, что пользователь вошел в систему.
type Mutation { # ... createArticle(title: String!, content: String!): Article @field(resolver: "ArticleMutator@create") @middleware(checks: ["auth:api"]) }
Во-первых, давайте сгенерируем класс мутации:
$ php artisan lighthouse:mutation ArticleMutator
Далее давайте обновим мутатор со следующей логикой:
namespace App\GraphQL\Mutations; use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; class ArticleMutator { /** * Return a value for the field. * * @param null $rootValue * @param mixed[] $args * @param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context * @return mixed */ public function create($rootValue, array $args, GraphQLContext $context) { $article = new \App\Article($args); $context->user()->articles()->save($article); return $article; } }
Примечание. Мы переименовали функцию resolve
по умолчанию для create
. Вам не нужно создавать новый класс для каждого преобразователя. Вместо этого вы можете сгруппировать логику вместе, если она имеет больше смысла.
Наконец, давайте запустим нашу новую мутацию и проверим вывод. Обязательно сохраните заголовок Authorization
из нашего предыдущего запроса на вкладке «HTTP Headers»:
mutation { createArticle( title:"Building a GraphQL Server with Laravel" content:"In case you're not currently familiar with it, GraphQL is a query language used to interact with your API..." ) { id author { id email } } }
Мы должны получить следующий вывод:
{ "data": { "createArticle": { "id": "56", "author": { "id": "1", "email": "[email protected]" } } } }
Подведение итогов
Напомним, что мы использовали Lighthouse для создания сервера GraphQL для нашего проекта Laravel. Мы использовали некоторые встроенные директивы схемы, создавали запросы и мутации, а также обрабатывали авторизацию и аутентификацию.
Lighthouse позволяет вам делать гораздо больше (например, создавать собственные директивы схемы), но для целей этой статьи мы придерживались основ и смогли настроить и запустить сервер GraphQL с довольно небольшим шаблоном.
В следующий раз, когда вам понадобится настроить API для мобильного или одностраничного приложения, обязательно рассмотрите GraphQL как способ запроса ваших данных!