Papooch / nestjs-cls

A continuation-local storage (async context) module compatible with NestJS's dependency injection.

Home Page:https://papooch.github.io/nestjs-cls/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Context not initialized on root path when using `setGlobalPrefix`

sailengsi opened this issue · comments

nrwl/nx#19842


Edit by @Papooch: Copied and edited form linked issue:

Current Behavior

  1. I have a project based on nx-v16.x that has been developed for a long time;
  2. Previously, Nestjs-cls was introduced and everything was functioning normally;
  3. When I added the Nest app to the project, the same reusable code, Nestjs-cls, became invalid. Even copying the previous project from the apps was invalid. As of now, the dependency removal and reinstallation, which used to work well, are no longer effective;
  4. In order to ensure that it is my project issue, Nestjs-cls issue, or nx issue, I created two warehouses respectively. One is a pure project generated based on NesCli, and the other is a project based on the current nx-v17-- preset=nest. They only introduced Nestjs-cls, and ultimately found that NestCli's is OK, while nx's is still invalid;

Expected Behavior

I hope Nestjs-cls can be used normally in Nest of nx

Steps to Reproduce

  1. https://github.com/sailengsi/nest-cls_ok ● Project based on nest-cli
  2. https://github.com/sailengsi/nx-nest-cls_bug ● Next project based on nx;

Both of the above two projects were exclusively, and only nestjs-cls were introduced in app.module.ts, and getId using ClsService in app.controller.ts was deleted by Console, since the input of nx projects was always undefined.

Nx Report

No abnormal output

Package Manager Version

pnpm 8.5.1

Operating System

  • macOS
  • Linux
  • Windows
  • Other (Please specify)

What's quite awkward is that the project has already been launched, and the local hassle I've been dealing with is completely ineffective

Hi, it seems strange to me that NX would break the library. I have been working on a project managed by NX before and we used nestjs-cls without a problem.

I will look at your reproduction in the morning.

As it turns out, this is neither a problem with NX, nor with nestjs-cls, but with Nest itself. It is related to app.setGlobalPrefix, which is automatically generated by NX, but not by nest create, which is the reason you only encountered it with NX.

You can read more about the issue in this thread, while the problem you're encountering is specifically described in this comment.

The problem is that with a global prefix (e.g. api), the middleware is mounted on /api/*, which does not match the route /api alone. However, it does match /api/something and all nested routes.

In your application, you can fix this in the following ways (until Nest fixes the issue):

  • Do not use global prefix.
  • Use an Interceptor or Guard instead of a Middleware to set up the CLS context.
  • Do not create any handlers for the /api route (as soon as you add any path to the controller or the method decorator), that means it will work for any of the following:
    • @Controller('something')
    • @Get('thing')
    • @Get(':parameter')
  • If you want to use middleware, and require that the context works on the root path (/api), do the following:
    • Set mount: false in the middleware options
    • In your AppModule, mount the middleware manually for all routes, plus the controller that handles the root path:
    consumer.apply(ClsMiddleware).forRoutes('*', AppController)

Hopefully, you can fix your issue and move forward with your project!

Ah ah, oh Maiga

When I woke up in the morning and opened GitHub to see your analysis, I suddenly realized.. After testing, it is indeed the case.

Looking back at the process of discovering this problem again, I feel a bit embarrassed:

  1. When accessing Nestjs-cls for the first time, it was not tested on GlobalPrefix, but directly on its own API, so there was nothing unusual and it was okay. Similarly, the second project remained the same;

  2. In the past two days, I was working on a new project that was empty, so I tested it on GlobalPrefix. I was stunned at the time;

  3. The most important moment came when I returned to my previous project. However, I didn't know how to test it on GlobalPrefix, and it was difficult to do so. At this time, I forgot to test my API and was a bit scared because the first version of this project based on nx had been online for more than ten days. I was thinking that the next press conference wouldn't cause such problems online..

OKOKOK, in fact, I usually don't directly do business logic for GlobalPrefix, just for testing. Unexpectedly, this test almost surprised me.

Thank you, thank you very much for your answer. I can finally let go of my heart that has been hanging in suspense for the past two days.