# 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
    );
}