#How to conditionally instantiate service class as a provider in NestJS?

10 messages · Page 1 of 1 (latest)

tawdry sonnet
#

I have a controller called User and two service classes: UserAdminService and UserSuperAdminService. When a user makes a request to any endpoint of the User controller, I want to check if the user making the request is an Admin or a Super Admin (based on the roles in the token) and instantiate the correct service (UserAdminService or UserSuperAdminService). Note that the two services implement the same UserService interface (just the internals of the methods that change a bit). How can I make this with NestJS?

What I tried:

user.module.ts

providers: [
    {
      provide: "UserService",
      inject: [REQUEST],
      useFactory: (request: Request) => UserServiceFactory(request)
    }
  ],

user-service.factory.ts

export function UserServiceFactory(request: Request) {

    const { realm_access } = JwtService.parseJwt(
        request.headers["authorization"].split(' ')[1]
    );
    if (realm_access["roles"].includes(RolesEnum.SuperAdmin))
        return UserSuperAdminService;
    else
        return UserAdminService;
}

user.controller.ts

  constructor(
      @Inject("UserService") private readonly userService: UserServiceInterface
  ) {}

One of the reasons my code is not working is because I am returning the classes and not the instantiated objects from the factory, but I want NestJS to resolve the services dependencies. Any ideas?

turbid onyx
#

Are you against having both of these classes created per request?

tawdry sonnet
#

Absolutely not

#

So... I could inject both services in the controller and use an if/else on each endpoint to call the method from the correct class?

#

This would create a lot of boilerplate. I was wondering if there was a more generic and concise approach

turbid onyx
#

I was gonna say you can add them both to the inject array and return whichever instance you need depending on the role

tawdry sonnet
#

Sounds nice. Could you please explain a bit more about the return whichever instance you need depending on the role part? How would I make this selection?

turbid onyx
tawdry sonnet
#

Thanks

#

That is pretty cool