lehh / nestjs-soap

Nestjs module wrapper for soap npm package
MIT License
21 stars 14 forks source link

Please add Request scope for the Injectable items #19

Closed Bishal18 closed 2 years ago

Bishal18 commented 2 years ago

Hi Team,

Thanks for the great work again. Could you please give provision for Request scope as that can be really necessary in various use cases. For example if we would need to change the soap url per request based on locale. This is an urgent need and would love to know if it can be done really soon and may be the ETA if you find this a valid request, @lehh .

lehh commented 2 years ago

@Bishal18,

Sorry for the delay.

You mean do requests for different URLs? Like, change the soap module URL on runtime? I don't think this is possible with the current architecture of the lib.

What you can do is create multiple imports of the SoapModule and then you can switch them based on the locale. Something like that maybe?

@Module({
  imports: [
    SoapModule.register(
      { clientName: 'EN_CLIENT', uri: 'http://yourserver/yourservice-en.wso?wsdl' },
    ),
    SoapModule.register(
      { clientName: 'PT_CLIENT', uri: 'http://yourserver/yourservice-pt.wso?wsdl' },
    ),
  ],
})

Then

export class ExampleService {
  constructor(
    @Inject('EN_CLIENT') private readonly enClient: Client,
    @Inject('PT_CLIENT') private readonly ptClient: Client
  ) {}

  async exampleFunction() {
    if (locale == "en") {
      this.enClient.YourClientFunctionAsync()
    }

    if (locale == "pt") {
      this.ptClient.YourClientFunctionAsync()
    }
  }
}
Bishal18 commented 2 years ago

Hi @lehh, what i wanted is the injection scope to be available while defining the module through forRootAsync, so that if i make the injection scope as request, ideally a new instance of the module would be handed out during every request, which would also mean reinstatiation.

Creating multiple imports is something which i really wanted to avoid as something similar is already used in our setup, but without avoiding conditions as all were needed at the same point for endpoints corresponding to different services. Here the use case is the same service is exposed through different baseUrls in different locales, so those baseURls are factory injected to the soap configuration module i have created. The missing link now is the injection scope to be available in the forRootAsync and we will set it as request so that a new instance is always instantiated for each request, where it will also take the correct baseURL, from the injected config. Hope this adds some insights.

lehh commented 2 years ago

Hi @Bishal18

I think I understand what you mean now. What you need is a scope property when creating async modules, right? Like this:

@Module({
  imports: [
    SoapModule.forRootAsync(
        clientName: 'CLIENT_TEST',
        useExisting: TestProvider,
        imports: [TestModule],
        scope: Scope.REQUEST
    ),
  ],
})

And this scope will be applied to the useExisting provider, in that example. Is that it?

Bishal18 commented 2 years ago

Yes that is exactly what i am looking for! Only, in my case, we have the usefactory to return the config for creating the module, and the locale based config is injected for this factory and the scope should be applicable for that injection. Basically something like this:

export const SoapService = SoapModule.forRootAsync({ clientName: 'client1', inject: [localeConfig], useFactory: (localeConfig: any) => getOptions(localeConfig), scope: Scope.REQUEST });

And this scope should indicate that my injected localeconfig reinstantiates per request.

lehh commented 2 years ago

All right. I believe this can be done pretty fast. I will start working on it as soon as I can. Thanks for the improvement suggestion!

Bishal18 commented 2 years ago

Glad to help in improving this in any way possible. Cheers! 🙂