# Field Directives

Field directives can be applied to any FieldDefinition (opens new window)

# FieldResolver

Perhaps the most important directive interface, a \Nuwave\Lighthouse\Support\Contracts\FieldResolver (opens new window) lets you add a resolver for a field through a directive.

It can be a great way to reuse resolver logic within a schema.

# FieldMiddleware

A \Nuwave\Lighthouse\Support\Contracts\FieldMiddleware (opens new window) directive allows you to wrap around the field resolver, just like Laravel Middleware (opens new window).

You may use it to handle incoming values before reaching the final resolver as well as the outgoing result of resolving the field.

namespace App\GraphQL\Directives;

use Closure;
use GraphQL\Type\Definition\ResolveInfo;
use Nuwave\Lighthouse\Schema\Directives\BaseDirective;
use Nuwave\Lighthouse\Schema\Values\FieldValue;
use Nuwave\Lighthouse\Support\Contracts\FieldMiddleware;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;

class ExampleDirective extends BaseDirective implements FieldMiddleware
{
    public static function definition(): string
    {
        return /** @lang GraphQL */ <<<'GRAPHQL'
directive @example on FIELD_DEFINITION
GRAPHQL;
    }

    public function handleField(FieldValue $fieldValue, Closure $next): FieldValue
    {
        $resolver = $fieldValue->getResolver();

        // If you have any work to do that does not require the resolver arguments, do it here.
        // This code is executed only once per field, whereas the resolver can be called often.

        $fieldValue->setResolver(function ($root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) use ($resolver) {
            // Do something before the resolver, e.g. validate $args, check authentication

            // Call the actual resolver
            $result = $resolver($root, $args, $context, $resolveInfo);

            // Do something with the result, e.g. transform some fields

            return $result;
        });

        // Keep the chain of adding field middleware going by calling the next handler.
        // Calling this before or after ->setResolver() allows you to control the
        // order in which middleware is wrapped around the field.
        return $next($fieldValue);
    }
}

Field middleware run in lexical definition order.

type Query {
  foo: ID @first @second
}

# FieldBuilderDirective

A \Nuwave\Lighthouse\Support\Contracts\FieldBuilderDirective (opens new window) directive allows modifying the database query that Lighthouse creates for a field.

This directive only works if the field resolver passes its builder through a call to $resolveInfo->enhanceBuilder(). Built-in field resolver directives that query the database do this, such as @all or @hasMany.

The following directives use the defined filter for resolving the query:

# FieldManipulator

A \Nuwave\Lighthouse\Support\Contracts\FieldManipulator (opens new window) directive can be used to manipulate the schema AST.

# ValidationDirective

This directive type is implemented as an abstract class rather than a pure interface and allows you to define complex validation rules for a field with ease.

Read more about it in the Validation section.

# ComplexityResolverDirective

A \Nuwave\Lighthouse\Support\Contracts\ComplexityResolverDirective (opens new window) directive allows you to overwrite the default query complexity calculation.