Skip to content

Commit c446495

Browse files
committed
chore: add context binding example
1 parent 38def91 commit c446495

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,8 @@ const myLoader = new DataLoader(objResults(myBatchLoader))
608608

609609
Looking to get started with a specific back-end? Try the [loaders in the examples directory](/examples).
610610

611+
Want to access your request context from your DataLoader functions? There's an [example of how to do that too](/examples/ContextBinding.md)!
612+
611613
## Other Implementations
612614

613615
Listed in alphabetical order

examples/ContextBinding.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Binding context to your DataLoaders
2+
3+
Sometimes in your DataLoader loading function you want to access a local context object of some sort, for example a [request context](https://www.apollographql.com/docs/apollo-server/data/resolvers/#the-context-argument) that could contain your database object, the current user, or some per-request telemetry. While not immediately obvious, it's simple to do this, and actually complements the best practice of creating a new DataLoader for each request. Here's how to do it (the example uses Apollo but this works with anything):
4+
5+
```js
6+
function context(args: ExpressContext): Context {
7+
const context = {
8+
db: getDB(),
9+
user: getUserFromSession(args)
10+
};
11+
context.loaders = {
12+
comments: new DataLoader(commentDataloader.bind(context), {
13+
context: context,
14+
})
15+
};
16+
return context;
17+
}
18+
19+
// Usage (`pg-promise` syntax)
20+
21+
const resolvers = {
22+
// ...
23+
posts: {
24+
comments: (parent: Post, args: Args, context: Context) => {
25+
return context.loaders.comments.loadMany(parent.comments);
26+
}
27+
}
28+
};
29+
30+
export async function commentDataloader(
31+
this: Context,
32+
parentIds: readonly number[]
33+
) {
34+
// Now you can also do fine-grained authorization with `this.user`
35+
return await this.db.manyOrNone(
36+
"SELECT * from comment WHERE id IN ($[parentIds:list]) ORDER BY id DESC",
37+
{ parentIds }
38+
);
39+
}
40+
```

0 commit comments

Comments
 (0)