Skip to content

Extend http interceptors in child module injector #36974

Closed
@miguel-leon

Description

@miguel-leon

🚀 feature request

Relevant Package

This feature request is for @angular/common/http

Description

Ability to extend http interceptors in child module injectors since it is fairly simple, but the api to achieve it is "private" in angular.

Describe the solution you'd like

I've already managed to do this by providing HttpHandler, HttpClient and HTTP_INTERCEPTORS manually in the lazy loaded module without importing HttpClientModule, since this module imports HttpClientXsrfModule which provides a fresh HTTP_INTERCEPTORS array, for the sake of reincluding HttpXsrfInterceptor (imho, but why again?).

If this explanation was hard to follow, here's the code

@NgModule({
	providers: [{
		provide: HttpClient,
		useClass: HttpClient
	}, {
		provide: HttpHandler,
		useClass: ɵHttpInterceptingHandler
	}, {
		provide: HTTP_INTERCEPTORS,
		deps: [Injector],
		useFactory: injector => [
			...ARRAY_OF_CHILDREN_INTERCEPTOR,
			...injector.parent.get(HTTP_INTERCEPTORS)
		]
	}]
})
export class FeatureModule {}

Here the "private" angular api is the class ɵHttpInterceptingHandler and the injector.parent part.

So, I think the most practical solution would be to maybe have an alternative HttpClientModule that does not import HttpClientXsrfModule so the interceptors array is not reset.

Or similarly, have both these modules without providers and have .forRoot(): ModuleWithProviders options for each, of which HttpClientModule.forRoot() would spread HttpClientXsrfModule.forRoot()'s providers.

Code again, if explanation was convoluted

class HttpClientModule {
	static forRoot(): ModuleWithProviders<HttpClientModule> {
		return {
			ngModule: HttpClientModule,
			providers: [
				// taken from source code as of version 9
				HttpClient,
				{provide: HttpHandler, useClass: HttpInterceptingHandler},
				HttpXhrBackend,
				{provide: HttpBackend, useExisting: HttpXhrBackend},
				BrowserXhr,
				{provide: XhrFactory, useExisting: BrowserXhr},

				// HttpClientXsrfModule providers
				...HttpClientXsrfModule.forRoot().providers
			]
		}
	}
}

Describe alternatives you've considered

Other, perhaps more suitable or powerful solutions, are definitely more difficult to implement.

One might be to extend capabilities of multi interceptors (or add another multi special type) to be able to extend themselves with the array of the parent injector.

Lastly, in another train of thought, this problem may delve a little into the "problem" that ModuleWithProviders doesn't solve thoroughly, being that provider inclusion is not completely controlled if the module in question imports another module that provides something. And even if the second module has a static ModuleWithProviders method for the same argument, you can't (not in a conventional manner) control which module version to import from within these methods.

i.e. ModuleWithProviders can't solve providers in deeper module imports with its intended design.
Hence, the most complicated solution would be to redesign this.

These are a lot less practical solutions, but since there's the section, I might as well mention them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P4A relatively minor issue that is not relevant to core functionsarea: common/httpIssues related to HTTP and HTTP Clientdesign complexity: low-hangingfeatureIssue that requests a new featurefeature: under considerationFeature request for which voting has completed and the request is now under considerationfeature: votes requiredFeature request which is currently still in the voting phase

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions