yakovenko/laravel-lighthouse-graphql-multi-schema is a Laravel package that provides multi-schema support for Lighthouse GraphQL. It allows you to manage multiple GraphQL schemas within a single Laravel application, streamlining development and extending functionality.
- PHP : ^8
- Laravel : ^9.0 || ^10.0 || ^11.0 || ^12.0
- Nuwave Lighthouse : ^6.0
- Multi-Schema IDE Helper: Generate IDE helper files for individual schemas
- Multi-Schema Validation: Validate GraphQL schemas with detailed error reporting
- Full compatibility with standard Lighthouse commands
- Schema isolation and safe file generation
- Full support for Laravel Octane and long-lived workers (Swoole, RoadRunner, etc).
See release notes for technical details.
You can install the package using Composer:
composer require yakovenko/laravel-lighthouse-graphql-multi-schemaPublish Configuration
After installing the package, you need to publish the configuration file by running the following command:
php artisan lighthouse-multi-schema:publish-configThis will create a configuration file named lighthouse-multi-schema.php in the config/ directory, where you can set up your GraphQL schemas.
Configuration
In the config/lighthouse-multi-schema.php file, you can define your schemas and their settings. Here's an example configuration:
return [
'multi_schemas' => [
'schema1' => [
'route_uri' => '/schema1-graphql',
'route_name' => 'schema1-graphql',
'schema_path' => base_path("graphql/schema1.graphql"),
'schema_cache_path' => env('LIGHTHOUSE_SCHEMA1_CACHE_PATH', base_path("bootstrap/cache/schema1-schema.php")),
'schema_cache_enable' => env('LIGHTHOUSE_SCHEMA1_CACHE_ENABLE', false),
'middleware' => [
// Always set the `Accept: application/json` header.
Nuwave\Lighthouse\Http\Middleware\AcceptJson::class,
// Logs in a user if they are authenticated. In contrast to Laravel's 'auth'
// middleware, this delegates auth and permission checks to the field level.
Nuwave\Lighthouse\Http\Middleware\AttemptAuthentication::class,
// Apply your custom middleware here.
// For example:
// App\Http\Middleware\ExampleSchemaMiddleware::class,
]
],
'schema2' => [
'route_uri' => '/schema2-graphql',
'route_name' => 'schema2-graphql',
'schema_path' => base_path("graphql/schema2.graphql"),
'schema_cache_path' => env('LIGHTHOUSE_SCHEMA2_CACHE_PATH', base_path("bootstrap/cache/schema2-schema.php")),
'schema_cache_enable' => env('LIGHTHOUSE_SCHEMA2_CACHE_ENABLE', false),
'middleware' => [ ... ]
],
// Add additional schemas as needed
],
];Middleware Support
You can now add middleware specific to each GraphQL schema, allowing you to apply different middleware configurations based on the schema being used. Specify the middleware classes in the middleware array for each schema, and they will be applied to the corresponding routes.
CSRF exceptions Laravel ^11
To disable CSRF verification for your GraphQL routes in Laravel 11, update bootstrap/app.php with the following configuration:
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'schema1-graphql',
'schema2-graphql',
// Add other routes as needed
]);
})
->create();In the code above, routes such as schema1-graphql and schema2-graphql are excluded from CSRF protection. For older Laravel versions, you can still add the routes in VerifyCsrfToken.php.
CSRF exceptions Laravel ^9.0 || ^10
Add your GraphQL routes to the CSRF exceptions.
Open the App/Http/Middleware/VerifyCsrfToken.php file and add your routes to the $except array.
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array<int, string>
*/
protected $except = [
'schema1-graphql',
'schema2-graphql',
// Add other routes as needed
];
}Create Directories for Each Schema
Organize your schema files into separate directories for each schema. The structure of these directories and how you split the files is up to you. Here's an example of one way to organize them:
example:
/graphql
βββ schema.graphql
βββ schema1.graphql
βββ schema2.graphql
βββ schema3.graphql
example:
/graphql
βββ models ( Type, Enum, Input ) # Shared types, enums, inputs
β βββ User.graphql
β βββ Order.graphql
β βββ Product.graphql
β
βββ v1 # Entry point for v1, imports shared models and v1-specific queries/mutations
β βββ v1.graphql ( #import /models/*.graphql, #import /request/*.graphql, general scalar, query and mutation, login, registration )
β βββ request ( Query, Mutation )
β βββ user_request.graphql ( meUpdate, me )
β βββ order_request.graphql ( meOrders )
β βββ product_request.graphql ( products, product )
β
βββ v2 # Entry point for v2, can import the same models and only add/override what's new
β βββ v2.graphql ( #import /models/*.graphql, #import /request/*.graphql, general scalar, query and mutation )
β βββ request ( Query, Mutation )
β βββ order_request.graphql ( orders, order )
β
βββ v3 # Entry point for v3, can import the same models and only add/override what's new
β βββ v3.graphql ( #import /models/*.graphql, #import /request/*.graphql, general scalar, query and mutation )
β βββ request ( Query, Mutation )
β β βββ user_request.graphql ( userCreate, userUpdate, userDelete, user, me, users )
β β βββ order_request.graphql ( orders, orders, orderUpdate, orderDelete, orderCreate )
β β βββ product_request.graphql ( products, product, productUpdate, productDelete, productCreate )
β βββ models ( Type, Enum, Input ) # if you need to personalize models according to the type of scheme
β
βββ api
βββ api.graphql ( #import /models/*.graphql, #import /request/*.graphql, general scalar, query and mutation )
βββ request ( Query, Mutation )
βββ models ( Type, Enum, Input )
The package provides several commands for managing your GraphQL schemas:
The lighthouse:clear-cache command is used to manage the cache for your GraphQL schemas. Below are the available usages:
1 - Clear Default Schema Cache
The following command removes the default schema cache:
php artisan lighthouse:clear-cache
2 - Clear All Schema Caches
To clear the cache for all GraphQL schemas, run:
php artisan lighthouse:clear-cache all
This deletes all cached schema files, ensuring any changes made to the schemas are reflected the next time they are accessed.
3 - Clear Cache for a Specific Schema
You can also clear the cache for any other schema by replacing {keyYourSchema} with the desired schema name:
php artisan lighthouse:clear-cache {keyYourSchema}
example:
php artisan lighthouse:clear-cache schema1
Replace {keyYourSchema} with the actual name of the schema you want to target. This will specifically remove the cache for that schema only.
Generate IDE helper files for improved type checking and autocompletion:
# Generate for default schema
php artisan lighthouse:multi-ide-helper
# Generate for specific schema
php artisan lighthouse:multi-ide-helper --schema=libraryThis creates schema-specific helper files:
schema-directives-{schema}.graphqlprogrammatic-types-{schema}.graphql_lighthouse_ide_helper.php(for default schema only)
Validate GraphQL schemas to catch errors before deployment:
# Validate default schema
php artisan lighthouse:multi-validate-schema
# Validate specific schema
php artisan lighthouse:multi-validate-schema --schema=librarySupported Error Types:
- Syntax errors (malformed GraphQL)
- Type errors (undefined types)
- Directive errors (undefined directives)
- Structural errors (invalid schema structure)
CI/CD Integration:
# Add to your deployment pipeline
php artisan lighthouse:multi-validate-schema
php artisan lighthouse:multi-ide-helperSchema 1: Access the GraphQL schema at:
domain.local/schema1-graphql
Schema 2: Access the GraphQL schema at:
domain.local/schema2-graphql
Schema 3: Access the GraphQL schema at:
domain.local/schema3-graphql
Once configured, you can use the defined routes for each schema in your application. Each route will utilize its corresponding GraphQL schema. You have a multi-schema setup that allows for an unlimited number of access points, each supporting various mutations and queries tailored to your specific needs. You can define each schema according to your project requirements. This flexibility allows you to create distinct schemas for different parts of your application, ensuring that each area can have customized queries and mutations as needed.
Author