# Directive Definitions

You can define GraphQL directives by placing a `@gqlDirective` before a:

-   Function declaration

```tsx
import { Int } from "grats";
/**
 * @gqlDirective on FIELD_DEFINITION
 */
function cost(args: { credits: Int }) {
  // ...
}
```

While the directive is defined as a function, unlike field resolvers, _Grats will not invoke your function_. However, having a function whose type matches the arguments of your directive can be useful for writing code which will accept the arguments of your directive.

To annotate part of your schema with a directive, see [`@gqlAnnotate`](./directive-annotations.md).

## Locations

The text after the `@gqlDirective` tag is parsed similarly to a a GraphQL directive definition:

1.  An optional name for the directive (the function name will be used if no name is provided)
2.  An optional `repeatable` keyword if the directive is repeatable
3.  The `on` keyword followed by a list of directive [locations](https://spec.graphql.org/October2021/#DirectiveLocation) separated by `|`.

```tsx
import { Int } from "grats";
/**
 * @gqlDirective cost repeatable on FIELD_DEFINITION | OBJECT
 */
function applyCost(args: { credits: Int }) {
  // ...
}
```

## Arguments

The first argument of the directive function is an object containing the directive’s GraphQL arguments. This mirrors the [Object-style map fields](./arguments.md#object-map-style-fields) style supported by field resolvers.

_All other arguments to the directive function are ignored by Grats._ This allows the function to be used as part of the implementation of the directive’s behavior.

```tsx
type SomeType = any;
/**
 * @gqlDirective on FIELD_DEFINITION
 */
function myDirective(args: { someArg: string }, someNonGqlArg: SomeType) {}
```

Default values in this style can be defined by using the `=` operator with destructuring. Note that you must perform the destructuring in the argument list, not in the function body:

```tsx
/**
 * @gqlDirective on FIELD_DEFINITION
 */
function myDirective({ greeting = "Hello" }: { greeting: string }) {}
```

Arguments can be marked as `@deprecated` by using the `@deprecated` JSDoc tag:

```tsx
/**
 * @gqlDirective on FIELD_DEFINITION
 */
function myDirective(args: {
  /** @deprecated Unused! */
  someArg?: string | null;
}) {
  // ...
}
```
