Skip to content

Commit

Permalink
chore: add context binding example
Browse files Browse the repository at this point in the history
  • Loading branch information
davedx committed May 9, 2022
1 parent 38def91 commit c446495
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,8 @@ const myLoader = new DataLoader(objResults(myBatchLoader))

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

Want to access your request context from your DataLoader functions? There's an [example of how to do that too](/examples/ContextBinding.md)!

## Other Implementations

Listed in alphabetical order
Expand Down
40 changes: 40 additions & 0 deletions examples/ContextBinding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Binding context to your DataLoaders

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):

```js
function context(args: ExpressContext): Context {
const context = {
db: getDB(),
user: getUserFromSession(args)
};
context.loaders = {
comments: new DataLoader(commentDataloader.bind(context), {
context: context,
})
};
return context;
}

// Usage (`pg-promise` syntax)

const resolvers = {
// ...
posts: {
comments: (parent: Post, args: Args, context: Context) => {
return context.loaders.comments.loadMany(parent.comments);
}
}
};

export async function commentDataloader(
this: Context,
parentIds: readonly number[]
) {
// Now you can also do fine-grained authorization with `this.user`
return await this.db.manyOrNone(
"SELECT * from comment WHERE id IN ($[parentIds:list]) ORDER BY id DESC",
{ parentIds }
);
}
```

0 comments on commit c446495

Please sign in to comment.