Skip to content

Commit

Permalink
fix(core): add RequestContext.createAsync() for Koa
Browse files Browse the repository at this point in the history
If the `next` handler needs to be awaited (like in Koa), one can now
use `RequestContext.createAsync()` method.

Closes #709
  • Loading branch information
B4nan committed Aug 9, 2020
1 parent 9da5a3e commit ae3bc0f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
7 changes: 7 additions & 0 deletions docs/docs/installation.md
Expand Up @@ -159,6 +159,13 @@ app.use((req, res, next) => {
});
```

> If the `next` handler needs to be awaited (like in Koa),
> use `RequestContext.createAsync()` instead.
>
> ```typescript
> app.use((ctx, next) => RequestContext.createAsync(orm.em, next));
> ```
More info about `RequestContext` is described [here](identity-map.md#request-context).

## Setting up the Commandline Tool
Expand Down
15 changes: 14 additions & 1 deletion packages/core/src/utils/RequestContext.ts
Expand Up @@ -14,13 +14,26 @@ export class RequestContext {
/**
* Creates new RequestContext instance and runs the code inside its domain.
*/
static create(em: EntityManager, next: (...args: any[]) => void) {
static create(em: EntityManager, next: (...args: any[]) => void): void {
const context = new RequestContext(em.fork(true, true));
const d = domain.create() as ORMDomain;
d.__mikro_orm_context = context;
d.run(next);
}

/**
* Creates new RequestContext instance and runs the code inside its domain.
* Async variant, when the `next` handler needs to be awaited (like in Koa).
*/
static async createAsync(em: EntityManager, next: (...args: any[]) => Promise<void>): Promise<void> {
const context = new RequestContext(em.fork(true, true));
const d = domain.create() as ORMDomain;
d.__mikro_orm_context = context;
await new Promise((resolve, reject) => {
d.run(() => next().then(resolve).catch(reject));
});
}

/**
* Returns current RequestContext (if available).
*/
Expand Down
13 changes: 13 additions & 0 deletions tests/RequestContext.test.ts
Expand Up @@ -22,6 +22,19 @@ describe('RequestContext', () => {
expect(RequestContext.currentRequestContext()).toBeUndefined();
});

test('create new context (async)', async () => {
expect(RequestContext.getEntityManager()).toBeUndefined();
await RequestContext.createAsync(orm.em, async () => {
const em = RequestContext.getEntityManager()!;
expect(em).not.toBe(orm.em);
// access UoW via property so we do not get the one from request context automatically
// @ts-ignore
expect(em.unitOfWork.getIdentityMap()).not.toBe(orm.em.unitOfWork.getIdentityMap());
expect(RequestContext.currentRequestContext()).not.toBeUndefined();
});
expect(RequestContext.currentRequestContext()).toBeUndefined();
});

test('request context does not break population', async () => {
const bible = new Book('Bible', new Author('God', 'hello@heaven.god'));
const author = new Author('Jon Snow', 'snow@wall.st');
Expand Down

0 comments on commit ae3bc0f

Please sign in to comment.