Lighthouse - пакет, у якому GraphQL API описується схемою-першою (schema-first): ви пишете файл graphql/schema.graphql, а директиви пов'язують поля з моделями Eloquent.
composer require nuwave/lighthouse
php artisan vendor:publish --tag=lighthouse-schema
type Query {
posts: [Post!]! @paginate(defaultCount: 20) @orderBy(column: "created_at", direction: DESC)
post(id: ID! @eq): Post @find
me: User @auth
}
type Mutation {
createPost(input: CreatePostInput! @spread): Post!
@guard
@canModel(ability: "create")
@create
}
input CreatePostInput {
title: String! @rules(apply: ["required", "max:255"])
body: String!
}
type Post {
id: ID!
title: String!
author: User! @belongsTo
}
Що тут відбувається без жодного PHP-коду:
@paginate- пагінація з типами для сторінок;@find,@all- вибірка моделей;@eq- умоваwhere;@belongsTo,@hasMany- зв'язки з пакетним завантаженням (без N+1);@guard- автентифікація (Sanctum чи інший guard),@canModel(і решта сімейства@can*:@canFind,@canQuery...) - політики Laravel. Стара універсальна@canу Lighthouse 6 позначена застарілою;@rules- звичайні правила валідації Laravel;@create,@update,@delete- мутації над моделями.
Власна логіка - резолвер-клас:
final class PublishPost
{
public function __invoke(null $_, array $args): Post
{
$post = Post::findOrFail($args['id']);
Gate::authorize('publish', $post);
$post->publish();
return $post;
}
}
publishPost(id: ID!): Post! @field(resolver: "App\\GraphQL\\Mutations\\PublishPost")
Що налаштувати одразу:
- безпеку в
config/lighthouse.php:max_query_depth,max_query_complexity, вимкнення інтроспекції в продакшені - за замовчуванням обмеження вимкнені; - кешування схеми в продакшені (
php artisan lighthouse:cache); - авторизацію на кожному полі, що віддає чутливі дані, а не лише на запитах верхнього рівня;
- тести: трейт
MakesGraphQLRequestsз методомgraphQL()і перевіркою відповіді.
Чим відрізняється від REST-контролерів: схема - єдине джерело правди і документація одночасно; клієнти (Apollo, urql) генерують з неї типи TypeScript.