# Extending Lighthouse
Lighthouse offers various extension points which can be utilized by package developers as well as end users.
# The Event System
Lighthouse offers a unified way of hooking into the complete execution lifecycle through Laravel's event system (opens new window). You may use any Service Provider to register listeners.
You can find a complete list of all dispatched events in the events API reference.
# Adding Directives
You can add your custom directives to Lighthouse by listening for the
RegisterDirectiveNamespaces
event.
Check out the test suite (opens new window) for an example of how this works.
# Changing the default resolver
The first priority when looking for a resolver is always given to FieldResolver
directives.
After that, Lighthouse attempts to find a default resolver.
The interface \Nuwave\Lighthouse\Support\Contracts\ProvidesResolver
(opens new window)
is expected to provide a resolver in case no resolver directive is defined for a field.
If the field is defined on the root Query
or Mutation
types,
Lighthouse's default implementation looks for a class with the capitalized name
of the field in the configured default location and calls its __invoke
method.
Non-root fields fall back to webonyx's default resolver (opens new window).
You may overwrite this by passing a callable
to \GraphQL\Executor\Executor::setDefaultFieldResolver
.
When the field is defined on the root Subscription
type, the \Nuwave\Lighthouse\Support\Contracts\ProvidesSubscriptionResolver
(opens new window)
interface is used instead.
# Use a custom GraphQLContext
The context is the third argument of any resolver function.
You may replace the default \Nuwave\Lighthouse\Schema\Context
with your own
implementation of the interface Nuwave\Lighthouse\Support\Contracts\GraphQLContext
.
The following example is just a starting point of what you can do:
<?php
namespace Nuwave\Lighthouse\Schema;
use Illuminate\Http\Request;
use Illuminate\Contracts\Auth\Authenticatable;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
class MyContext implements GraphQLContext
{
/**
* An instance of the incoming HTTP request.
*
* @var \Illuminate\Http\Request
*/
public $request;
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Get instance of request.
*
* @return \Illuminate\Http\Request
*/
public function request(): Request
{
return $this->request;
}
/**
* Get instance of authenticated user.
*
* May be null since some fields may be accessible without authentication.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user(): ?Authenticatable
{
// TODO implement yourself
}
}
You need a factory that creates an instance of \Nuwave\Lighthouse\Support\Contracts\GraphQLContext
.
This factory class needs to implement \Nuwave\Lighthouse\Support\Contracts\CreatesContext
.
<?php
namespace App;
use Illuminate\Http\Request;
use Nuwave\Lighthouse\Support\Contracts\CreatesContext;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
class MyContextFactory implements CreatesContext
{
/**
* Generate GraphQL context.
*
* @param \Illuminate\Http\Request $request
* @return \Nuwave\Lighthouse\Support\Contracts\GraphQLContext
*/
public function generate(Request $request): GraphQLContext
{
return new MyContext($request);
}
}
Rebind the interface in a service provider (e.g. your AppServiceProvider
or a new GraphQLServiceProvider
):
public function register(): void
{
$this->app->bind(
\Nuwave\Lighthouse\Support\Contracts\CreatesContext::class,
\App\MyContextFactory::class
);
}