Skip to content

Commit c3045a3

Browse files
sarahxsandersbenjieJoviDeCroock
authored andcommitted
docs: cleanup and fixes (#4419)
This PR has some cleanup tasks: - Reorganized the information architecture a bit so that sections flow better - Fixed broken links - Fixed a code snippet that wasn't closed off/bleeding into a section - Updated auth strategy guide w/ callouts for not using resolver auth in production per @benjie request Please let me know if there are any other tweaks I can include! --------- Co-authored-by: Benjie <[email protected]> Co-authored-by: Jovi De Croock <[email protected]>
1 parent 97276ed commit c3045a3

19 files changed

+84
-37
lines changed

website/pages/docs/_meta.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,44 @@ const meta = {
22
index: '',
33
'-- 1': {
44
type: 'separator',
5-
title: 'GraphQL.JS Tutorial',
5+
title: 'Getting Started',
66
},
77
'getting-started': '',
88
'running-an-express-graphql-server': '',
99
'graphql-clients': '',
10+
'authentication-and-express-middleware': '',
11+
'-- 2': {
12+
type: 'separator',
13+
title: 'Core Concepts',
14+
},
1015
'basic-types': '',
1116
'passing-arguments': '',
1217
'object-types': '',
1318
'mutations-and-input-types': '',
14-
'authentication-and-express-middleware': '',
15-
'authorization-strategies': '',
16-
'-- 2': {
19+
nullability: '',
20+
'abstract-types': '',
21+
'custom-scalars': '',
22+
'-- 3': {
1723
type: 'separator',
1824
title: 'Advanced Guides',
1925
},
2026
'constructing-types': '',
21-
nullability: '',
22-
'abstract-types': '',
2327
'oneof-input-objects': '',
2428
'defer-stream': '',
2529
subscriptions: '',
2630
'type-generation': '',
2731
'cursor-based-pagination': '',
28-
'custom-scalars': '',
2932
'advanced-custom-scalars': '',
3033
'operation-complexity-controls': '',
3134
'n1-dataloader': '',
3235
'caching-strategies': '',
3336
'resolver-anatomy': '',
3437
'graphql-errors': '',
3538
'using-directives': '',
36-
'-- 3': {
37-
type: 'separator',
38-
title: 'Testing',
39-
},
39+
'authorization-strategies': '',
4040
'-- 4': {
4141
type: 'separator',
42-
title: 'FAQ',
42+
title: 'Production & Scaling',
4343
},
4444
'going-to-production': '',
4545
'scaling-graphql': '',

website/pages/docs/abstract-types.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
title: Abstract types in GraphQL.js
33
---
44

5+
# Abstract types in GraphQL.js
6+
57
GraphQL includes two kinds of abstract types: interfaces and unions. These types let a single
68
field return values of different object types, while keeping your schema type-safe.
79

@@ -206,7 +208,7 @@ union in future, and thus ensure that you have a default case to handle addition
206208

207209
## Additional resources
208210

209-
- [Constructing Types](https://www.graphql-js.org/docs/constructing-types/)
211+
- [Constructing Types](./constructing-types)
210212
- GraphQL Specification:
211213
- [Interfaces](https://spec.graphql.org/October2021/#sec-Interfaces)
212214
- [Unions](https://spec.graphql.org/October2021/#sec-Unions)

website/pages/docs/authentication-and-express-middleware.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ title: Using Express Middleware with GraphQL.js
33
sidebarTitle: Using Express Middleware
44
---
55

6+
# Authentication and Express Middleware
7+
68
import { Tabs } from 'nextra/components';
79

810
It's simple to use any Express middleware in conjunction with `graphql-http`. In particular, this is a great pattern for handling authentication.
@@ -101,4 +103,4 @@ If you aren't familiar with any of these authentication mechanisms, we recommend
101103

102104
If you've read through the docs linearly to get to this point, congratulations! You now know everything you need to build a practical GraphQL API server.
103105

104-
Want to control access to specific operations or fields? See [Authorization Strategies](\pages\docs\authorization-strategies.mdx).
106+
Want to control access to specific operations or fields? See [Authorization Strategies](./authorization-strategies).

website/pages/docs/authorization-strategies.mdx

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
title: Authorization Strategies
33
---
44

5+
import { Callout } from 'nextra/components'
6+
57
GraphQL gives you complete control over how to define and enforce access control.
68
That flexibility means it's up to you to decide where authorization rules live and
79
how they're enforced.
@@ -10,6 +12,12 @@ This guide covers common strategies for implementing authorization in GraphQL
1012
servers using GraphQL.js. It assumes you're authenticating requests and passing a user or
1113
session object into the `context`.
1214

15+
<Callout type="info" emoji="ℹ️">
16+
In production systems authorization should be handled in your business logic layer, not your
17+
GraphQL resolvers. GraphQL is intended to be a thin execution layer that calls into your application's
18+
domain logic, which enforces access control.
19+
</Callout>
20+
1321
## What is authorization?
1422

1523
Authorization determines what a user is allowed to do. It's different from
@@ -23,11 +31,7 @@ In GraphQL, authorization typically involves restricting:
2331

2432
## Resolver-based authorization
2533

26-
> **Note:**
27-
> All examples assume you're using Node.js 20 or later with [ES module (ESM) support](https://nodejs.org/api/esm.html) enabled.
28-
29-
The simplest approach is to enforce access rules directly inside resolvers
30-
using the `context.user` value:
34+
You can implement simple authorization checks directly in resolvers using `context.user`:
3135

3236
```js
3337
export const resolvers = {
@@ -42,12 +46,15 @@ export const resolvers = {
4246
};
4347
```
4448

45-
This works well for smaller schemas or one-off checks.
49+
This approach can help when you're learning how context works or building quick prototypes.
50+
However, for production systems, you should enforce access control in your business logic layer
51+
rather than in GraphQL resolvers.
4652

4753
## Centralizing access control logic
4854

49-
As your schema grows, repeating logic like `context.user.role !=='admin'`
50-
becomes error-prone. Instead, extract shared logic into utility functions:
55+
If you're experimenting or building a small project, repeating checks like
56+
`context.user.role !== 'admin'` across resolvers can become error-prone. One
57+
way to manage that duplication is by extracting shared logic into utility functions:
5158

5259
```js
5360
export function requireUser(user) {
@@ -64,7 +71,7 @@ export function requireRole(user, role) {
6471
}
6572
```
6673

67-
You can use these helpers in resolvers:
74+
Then use those helpers in resolvers:
6875

6976
```js
7077
import { requireRole } from './auth.js';
@@ -79,7 +86,11 @@ export const resolvers = {
7986
};
8087
```
8188

82-
This pattern makes your access rules easier to read, test, and update.
89+
This pattern improves readability and reusability, but like all resolver-based authorization,
90+
it's best suited for prototypes or early-stage development.
91+
92+
For production use, move authorization into your business logic layer. These helpers can still be useful
93+
there, but they should be applied outside the GraphQL execution layer.
8394

8495
## Field-level access control
8596

@@ -148,8 +159,7 @@ resolver-based checks and adopt directives later if needed.
148159

149160
## Best practices
150161

151-
- Keep authorization logic close to business logic. Resolvers are often the
152-
right place to keep authorization logic.
162+
- Keep authorization logic in your business logic layer, not in your GraphQL resolvers.
153163
- Use shared helper functions to reduce duplication and improve clarity.
154164
- Avoid tightly coupling authorization logic to your schema. Make it
155165
reusable where possible.

website/pages/docs/basic-types.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
title: Basic Types
33
---
44

5+
# Basic Types
6+
57
import { Tabs } from 'nextra/components';
68

79
In most situations, all you need to do is to specify the types for your API using the GraphQL schema language, taken as an argument to the `buildSchema` function.

website/pages/docs/caching-strategies.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export const resolvers = {
142142
- This isn't a long-lived cache. Combine it with other layers for broader coverage.
143143

144144
To read more about DataLoader and the N+1 problem,
145-
see [Solving the N+1 Problem with DataLoader](https://github.com/graphql/dataloader).
145+
see [Solving the N+1 Problem with DataLoader](./n1-dataloader).
146146

147147
## Operation result caching
148148

website/pages/docs/constructing-types.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
title: Constructing Types
33
---
44

5+
# Constructing Types
6+
57
import { Tabs } from 'nextra/components';
68

79
For many apps, you can define a fixed schema when the application starts, and define it using GraphQL schema language. In some cases, it's useful to construct a schema programmatically. You can do this using the `GraphQLSchema` constructor.

website/pages/docs/cursor-based-pagination.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ title: Implementing Cursor-based Pagination
44

55
import { Callout } from "nextra/components";
66

7+
# Implementing Cursor-based Pagination
8+
79
When a GraphQL API returns a list of data, pagination helps avoid
810
fetching too much data at once. Cursor-based pagination fetches items
911
relative to a specific point in the list, rather than using numeric offsets.

website/pages/docs/defer-stream.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
title: Enabling Defer & Stream
33
---
44

5+
# Enabling Defer and Stream
6+
57
import { Callout } from 'nextra/components'
68

79
<Callout type="info" emoji="ℹ️">

website/pages/docs/going-to-production.mdx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
title: Going to Production
33
---
44

5-
Bringing a GraphQL.js server into production involves more than deploying code. In production,
6-
a GraphQL server should be secure, fast, observable, and protected against abusive queries.
5+
# Going to Production
6+
7+
GraphQL.JS contains a few development checks which in production will cause slower performance and
8+
an increase in bundle-size. Every bundler goes about these changes different, in here we'll list
9+
out the most popular ones.
710

811
GraphQL.js includes development-time checks that are useful during local testing but should
912
be disabled in production to reduce overhead. Additional concerns include caching, error handling,

0 commit comments

Comments
 (0)