Skip to content

Commit c431fc0

Browse files
benjieyaacovCR
authored andcommitted
Indicate that field arguments should always be preferred over directives (#4417)
Follow up to #4401
1 parent 797fcaa commit c431fc0

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

website/pages/docs/using-directives.mdx

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,10 @@ You can apply directives to:
145145

146146
- Fields
147147
- Fragment spreads
148+
- Named fragments
148149
- Inline fragments
150+
- Operations (query, mutation or subscription)
151+
- Variable definitions
149152

150153
The following examples show how to apply directives:
151154

@@ -253,6 +256,49 @@ Some common use cases for custom directives include:
253256
- **Observability**: `@log`, `@tag(name: "important")`, or `@metrics(id: "xyz")`
254257
- **Execution control**: Mask or transform fields at runtime with schema visitors
255258
259+
## When to avoid custom directives
260+
261+
Custom directives should not be used where an argument could achieve the same
262+
goal. Custom directives in GraphQL requests complicate caching (particularly
263+
normalized caches) and are less well understood by tooling such as GraphQL; by
264+
using arguments instead we maximize compatibility and consistency. For example,
265+
our `@uppercase` directive would fit naturally as a field argument:
266+
267+
```js
268+
import {
269+
graphql,
270+
buildSchema,
271+
} from 'graphql';
272+
273+
const schema = buildSchema(`
274+
enum Format {
275+
VERBATIM
276+
UPPERCASE
277+
}
278+
type Query {
279+
greeting(format: Format! = VERBATIM): String
280+
}
281+
`);
282+
283+
const rootValue = {
284+
greeting: (source, args) => {
285+
const result = 'Hello, world';
286+
287+
if (args.format === "UPPERCASE") {
288+
return result.toUpperCase();
289+
}
290+
291+
return result;
292+
},
293+
};
294+
295+
const query = `
296+
query {
297+
greeting(format: UPPERCASE)
298+
}
299+
`;
300+
301+
256302
## Best practices
257303

258304
When working with custom directives in GraphQL.js, keep the following best practices in mind:
@@ -261,6 +307,7 @@ When working with custom directives in GraphQL.js, keep the following best pract
261307
manually.
262308
- Weigh schema-driven logic against resolver logic. Directives can make queries more expressive, but they
263309
may also hide behavior from developers reading the schema or resolvers.
310+
- Always prefer field arguments over directives where possible.
264311
- Keep directive behavior transparent and debuggable. Since directives are invisible at runtime unless
265312
logged or documented, try to avoid magic behavior.
266313
- Use directives when they offer real value. Avoid overusing directives to replace things that could be
@@ -272,4 +319,4 @@ writing custom validation rules to enforce correct usage.
272319
273320
- [GraphQL Specification: Directives](https://spec.graphql.org/draft/#sec-Language.Directives)
274321
- The Guild's guide on [Schema Directives](https://the-guild.dev/graphql/tools/docs/schema-directives)
275-
- Apollo Server's guide on [Directives](https://www.apollographql.com/docs/apollo-server/schema/directives)
322+
- Apollo Server's guide on [Directives](https://www.apollographql.com/docs/apollo-server/schema/directives)

0 commit comments

Comments
 (0)