Last active
November 15, 2019 19:00
-
-
Save tw3/0debb1a7c9a15cc79fee3338216977c6 to your computer and use it in GitHub Desktop.
Serializer that stores and pulls a generic configuration object from the HttpHeader instance so as to configure an interceptor on a per-request basis
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { HttpHeaders, HttpRequest } from '@angular/common/http'; | |
import { isNullOrUndefined } from '../../util/misc-util'; | |
import { HttpClientHeaders, HttpClientOptions } from './http-client-options'; | |
/** | |
* Unfortunately Angular does not provide a way to pass metadata/configs into interceptors so | |
* we have to do it ourselves. | |
* | |
* https://github.com/angular/angular/issues/18155 | |
*/ | |
export interface PullInterceptorConfigResult<T> { | |
request: HttpRequest<any>; // NOSONAR | |
config: T | undefined; | |
} | |
export class InterceptorRequestConfigSerializer { | |
static pullConfig<T>(req: HttpRequest<any>, configName: string): PullInterceptorConfigResult<T> { // NOSONAR | |
return InterceptorRequestHeaderConfigSerializer.pullConfig(req, configName); | |
} | |
static setConfig(options: HttpClientOptions, configName: string, config: object): HttpClientOptions | undefined { | |
return InterceptorRequestHeaderConfigSerializer.setConfig(options, configName, config); | |
} | |
} | |
class InterceptorRequestHeaderConfigSerializer { | |
private static readonly INTERCEPTOR_HEADER_PROPERTY_PREFIX = '__interceptor-config__'; | |
static pullConfig<T>(req: HttpRequest<any>, configName: string): PullInterceptorConfigResult<T> { // NOSONAR | |
if (!(req.headers instanceof HttpHeaders)) { | |
// Not an instance of HttpHeaders -> no config set | |
return { request: req, config: undefined }; | |
} | |
const headersInst: HttpHeaders = req.headers; | |
const headerProperty: string = this.getHeaderProperty(configName); | |
const config: T = headersInst[headerProperty]; | |
return { request: req, config }; | |
} | |
static setConfig(options: HttpClientOptions, configName: string, config: object): HttpClientOptions | undefined { | |
if (isNullOrUndefined(options)) { | |
return undefined; | |
} | |
const headersInst: HttpHeaders = this.getHeadersInstance(options.headers); | |
const headerProperty: string = this.getHeaderProperty(configName); | |
headersInst[headerProperty] = config; | |
return { | |
...options, | |
headers: headersInst | |
}; | |
} | |
private static getHeadersInstance(inputHeaders: HttpClientHeaders): HttpHeaders { | |
if (inputHeaders instanceof HttpHeaders) { | |
return inputHeaders; | |
} | |
if (isNullOrUndefined(inputHeaders)) { | |
return new HttpHeaders(); | |
} | |
return new HttpHeaders(inputHeaders); | |
} | |
private static getHeaderProperty(configName: string): string { | |
return `${this.INTERCEPTOR_HEADER_PROPERTY_PREFIX}${configName}`; | |
} | |
} | |
// Backup class in case the above class doesn't work | |
// eslint-disable-next-line @typescript-eslint/no-unused-vars | |
class InterceptorRequestHeaderConfigSerializer2 { | |
private static readonly INTERCEPTOR_HEADER_PREFIX = 'X-Interceptor-Headers-'; | |
/** | |
* Gets the interceptor header and removes it | |
*/ | |
static pullConfig<T>(req: HttpRequest<any>, configName: string): PullInterceptorConfigResult<T> { // NOSONAR | |
let headerValue: T; | |
const headersInst: HttpHeaders = this.getHeadersInstance(req.headers); | |
const headerKey: string = this.getHeaderKey(configName); | |
const headerValueStr: string = headersInst.get(headerKey); | |
if (!isNullOrUndefined(headerValueStr)) { | |
headerValue = JSON.parse(headerValueStr); | |
req = req.clone({ | |
headers: req.headers.delete(headerKey) | |
}); | |
} | |
return { request: req, config: headerValue }; | |
} | |
static setConfig(options: HttpClientOptions, configName: string, config: object): HttpClientOptions | undefined { | |
if (isNullOrUndefined(options)) { | |
return undefined; | |
} | |
const headersInst: HttpHeaders = this.getHeadersInstance(options.headers); | |
const headerKey: string = this.getHeaderKey(configName); | |
const headerValueStr: string = JSON.stringify(config); | |
const newHeadersInst: HttpHeaders = headersInst.set(headerKey, headerValueStr); | |
return { | |
...options, | |
headers: newHeadersInst | |
}; | |
} | |
private static getHeadersInstance(inputHeaders: HttpClientHeaders): HttpHeaders { | |
if (inputHeaders instanceof HttpHeaders) { | |
return inputHeaders; | |
} | |
if (isNullOrUndefined(inputHeaders)) { | |
return new HttpHeaders(); | |
} | |
return new HttpHeaders(inputHeaders); | |
} | |
private static getHeaderKey(configName: string): string { | |
return `${this.INTERCEPTOR_HEADER_PREFIX}${configName}`; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment