apollo-server/docs/source/features/directives.md
Jake Dawkins 673a580660 docs: Make schema directive example clearer (#1715)
The schema directive example [here](https://www.apollographql.com/docs/apollo-server/v2/features/directives.html) doesn't work. The package being imported was meant to be an _example_, unworking directive. This is confusing for people trying to run this example, so I replaced it with a real one.
2018-09-24 20:34:46 +03:00

88 lines
3.4 KiB
Markdown

---
title: Using schema directives
description: Using schema directives to transform schema types, fields, and arguments
---
A _directive_ is an identifier preceded by a `@` character, optionally followed by a list of named arguments, which can appear after almost any form of syntax in the GraphQL query or schema languages. Here's an example from the [GraphQL draft specification](http://facebook.github.io/graphql/draft/#sec-Type-System.Directives) that illustrates several of these possibilities:
```typescript
directive @deprecated(
reason: String = "No longer supported"
) on FIELD_DEFINITION | ENUM_VALUE
type ExampleType {
newField: String
oldField: String @deprecated(reason: "Use `newField`.")
}
```
As you can see, the usage of `@deprecated(reason: ...)` _follows_ the field that it pertains to (`oldField`), though the syntax might remind you of "decorators" in other languages, which usually appear on the line above. Directives are typically _declared_ once, using the `directive @deprecated ... on ...` syntax, and then _used_ zero or more times throughout the schema document, using the `@deprecated(reason: ...)` syntax.
## Default Directives
GraphQL provides several default directives: [`@deprecated`](http://facebook.github.io/graphql/draft/#sec--deprecated), [`@skip`](http://facebook.github.io/graphql/draft/#sec--skip), and [`@include`](http://facebook.github.io/graphql/draft/#sec--include).
* [`@deprecated`](http://facebook.github.io/graphql/draft/#sec--deprecated)`(reason: String)` - marks field as deprecated with message
* [`@skip`](http://facebook.github.io/graphql/draft/#sec--skip)`(if: Boolean!)` - GraphQL execution skips the field if true by not calling the resolver
* [`@include`](http://facebook.github.io/graphql/draft/#sec--include)`(if: Boolean!)` - Calls resolver for annotated field if true
## Using custom schema directives
To use a custom schema directive, pass the implemented class to Apollo Server via the `schemaDirectives` argument, which is an object that maps directive names to directive implementations:
```js
const { ApolloServer, gql, SchemaDirectiveVisitor } = require('apollo-server');
const { defaultFieldResolver } = require('graphql');
// Create (or import) a custom schema directive
class UpperCaseDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
const { resolve = defaultFieldResolver } = field;
field.resolve = async function (...args) {
const result = await resolve.apply(this, args);
if (typeof result === 'string') {
return result.toUpperCase();
}
return result;
};
}
}
// Construct a schema, using GraphQL schema language
const typeDefs = gql`
directive @upper on FIELD_DEFINITION
type Query {
hello: String @upper
}
`;
// Provide resolver functions for your schema fields
const resolvers = {
Query: {
hello: (root, args, context) => {
return 'Hello world!';
},
},
};
// Add directive to the ApolloServer constructor
const server = new ApolloServer({
typeDefs,
resolvers,
schemaDirectives: {
upper: UpperCaseDirective,
}
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`)
});
```
The implementation of `UpperCaseDirective` takes care of changing the resolver and modifying the schema if necessary.
## Building your own
To learn how to implement your own schema directives, read [this guide](./creating-directives.html).