I work with a monorepo which includes several NestJS apps, all deployed separately. An authentication guard is needed to parse JWTs and since it's the same one for all apps, I need to make it "common". My strategy is the following structure:
- root
- - packages
- - - app1
- - - app2
- - - guards
- - - - src
- - - - dist
The way our company works with monorepos is by building common packages, and importing from dist. So the guard I want should be written under guards/src, then built and imported from guards/dist, so for example:
// app1/src/main.ts
import { AuthGuard } from 'guards/dist`;
async function bootstrap() {
// ...
app.useGlobalGuards(new AuthGuard());
// ...
}
The issue is as follows: Following the NestJS docs for JSW handling I built my guard:
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private jwtService: JwtService) {}
}
But when using it in the above example (in new AuthGuard()), I am required to provide the argument jwtService which would normally be injected by a module.
But this guard isn't used in a module, nor would I want to include the JwtService in every app separately - that defeats the purpose of a common auth guard!
I'm not sure how to target this. The options I see now are:
- Make
guardsexport a module instead of an injectable. (issue: how to implement guards this way?) - Skip
JwtServiceand use another library for parsing JWTs. (issue: specific solution that doesn't solve future similar issues). - Instantiate
JwtServicemyself, instead of relying on dependency injection. (issue: defeats Nest's architecture design).
What say you?