Skip to content

Commit

Permalink
docs: update docs and tests for gql (#59)
Browse files Browse the repository at this point in the history
* context setup for GQL no longer requires `useEnterWith`
  • Loading branch information
Papooch authored Feb 18, 2023
1 parent 76a6e07 commit 8e39ff7
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 20 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/run-tests.workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ concurrency:
jobs:
run_tests:
runs-on: ubuntu-latest
strategy:
matrix:
node: [16, 18]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.x
node-version: ${{ matrix.node }}.x
cache: npm
- run: npm ci --audit=false
- run: npm run lint
Expand Down
26 changes: 17 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export class AppModule implements NestModule {
}
```

Sometimes, however, that won't be enough, because the middleware could be mounted too late and you won't be able to use it in other middlewares (**as is the case of GQL resolvers**). In that case, you can mount it directly in the bootstrap method:
Sometimes, however, that won't be enough, because the middleware could be mounted too late and you won't be able to use it in other middlewares that need to run prior to that. In that case, you can mount it directly in the bootstrap method:

```ts
function bootstrap() {
Expand Down Expand Up @@ -750,11 +750,11 @@ The `ClsInterceptor` only uses the safe `run()` method.

The table below outlines the compatibility with some platforms:

| | REST | GQL | WS | Microservices |
| :----------------------------------------------------------: | :------------------------------------------------------: | :-------------------------------------------------------------: | :----------------: | :-----------: |
| **ClsMiddleware** || ✔<br>must be _mounted manually_<br>and use `useEnterWith: true` |||
| **ClsGuard** <br>(uses `enterWith`) || |[\*](#websockets) ||
| **ClsInterceptor** <br>(context inaccessible<br>in _Guards_) | ✔<br>context also inaccessible<br>in _Exception Filters_ | |[\*](#websockets) ||
| | REST | GQL | WS | Microservices |
| :----------------------------------------------------------: | :------------------------------------------------------: | :-: | :----------------: | :-----------: |
| **ClsMiddleware** || |||
| **ClsGuard** <br>(uses `enterWith`) || |[\*](#websockets) ||
| **ClsInterceptor** <br>(context inaccessible<br>in _Guards_) | ✔<br>context also inaccessible<br>in _Exception Filters_ | |[\*](#websockets) ||

## REST

Expand All @@ -767,7 +767,15 @@ Tested with:

## GraphQL

For GraphQL, the `ClsMiddleware` needs to be [mounted manually](#manually-mounting-the-middleware) with `app.use(...)` in order to correctly set up the context for resolvers. Additionally, you have to pass `useEnterWith: true` to the `ClsMiddleware` options, because the context gets lost otherwise due to [an issue with CLS and Apollo](https://github.com/apollographql/apollo-server/issues/2042) (sadly, the same is true for [Mercurius](https://github.com/Papooch/nestjs-cls/issues/1)). This method is functionally identical to just using the `ClsGuard`.
### `@nestjs/graphql >= 10`,

Since v10, this package is 100% compatible with GraphQL resolvers and the preferred way is to use the `ClsMiddleware` with the `mount` option.

Using an interceptor or a guard may result in that enhancer triggering multiple times in case of nested resolvers, which may mess with ID generation.

### `@nestjs/graphql < 10`

For older versions of graphql, the `ClsMiddleware` needs to be [mounted manually](#manually-mounting-the-middleware) with `app.use(...)` in order to correctly set up the context for resolvers. Additionally, you have to pass `useEnterWith: true` to the `ClsMiddleware` options, because the context gets lost otherwise due to [an issue with CLS and Apollo](https://github.com/apollographql/apollo-server/issues/2042) (sadly, the same is true for [Mercurius](https://github.com/Papooch/nestjs-cls/issues/1)). This method is functionally identical to just using the `ClsGuard`.

Alternatively, you can use the `ClsInterceptor`, which uses the safer `AsyncLocalStorage#run` (thanks to [andreialecu](https://github.com/Papooch/nestjs-cls/issues/5)), but remember that using it makes CLS unavailable in _Guards_.

Expand All @@ -778,11 +786,11 @@ Tested with:

## Others

Use the `ClsGuard` or `ClsInterceptor` to set up context with any other platform. This is still _experimental_, as there are no test and I can't guarantee it will work with your platform of choice, but there's nothing that would indicate otherwise.
Use the `ClsGuard` or `ClsInterceptor` to set up context with any other platform.There are no explicit test for other transports, so I can't guarantee it will work with your platform of choice, but there's nothing that would indicate otherwise.

> If you decide to try this package with a platform that is not listed here, **please let me know** so I can add the compatibility notice.
Below are listed platforms with which it is confirmed to work.
Below are listed platforms with which it is confirmed to work:

### Websockets

Expand Down
10 changes: 5 additions & 5 deletions test/gql/gql-apollo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver } from '@nestjs/apollo';

let app: INestApplication;
describe('GQL Apollo App - Manually bound Middleware in Bootstrap', () => {
describe('GQL Apollo App - Auto bound Middleware', () => {
@Module({
imports: [
ClsModule.forRoot({ global: true }),
ClsModule.forRoot({
global: true,
middleware: { mount: true, generateId: true },
}),
ItemModule,
GraphQLModule.forRoot({
driver: ApolloDriver,
Expand All @@ -25,9 +28,6 @@ describe('GQL Apollo App - Manually bound Middleware in Bootstrap', () => {
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
app.use(
new ClsMiddleware({ useEnterWith: true, generateId: true }).use,
);
await app.init();
});

Expand Down
10 changes: 5 additions & 5 deletions test/gql/gql-mercurius.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import { GraphQLModule } from '@nestjs/graphql';
import { MercuriusDriver } from '@nestjs/mercurius';

let app: NestFastifyApplication;
describe('GQL Mercurius App - Manually bound Middleware in Bootstrap', () => {
describe('GQL Mercurius App - Auto bound Middleware', () => {
@Module({
imports: [
ClsModule.forRoot({ global: true }),
ClsModule.forRoot({
global: true,
middleware: { mount: true, generateId: true },
}),
ItemModule,
GraphQLModule.forRoot({
driver: MercuriusDriver,
Expand All @@ -30,9 +33,6 @@ describe('GQL Mercurius App - Manually bound Middleware in Bootstrap', () => {
new FastifyAdapter(),
{ logger: false },
);
app.use(
new ClsMiddleware({ generateId: true, useEnterWith: true }).use,
);
await app.init();
await app.getHttpAdapter().getInstance().ready();
});
Expand Down

0 comments on commit 8e39ff7

Please sign in to comment.