Reputation: 125
I am new to NestJS and have been looking at a couple of solutions but haven't found a way. My API returns list of users, the users are either read from the cache if present or from the DB and based on this I need to set the headers. I want the interceptor to handle this part.
My Controller
@UseInterceptors(CacheOrServiceHeaderInterceptor)
@Get('users')
public async users(
@Query('id') clinicianId: number,
@Query('name') specialtyName: string,
){
const setFlags: MetaFlags = {setCacheHeader: false, setServiceHeader: false};
const data = await this.service.getUsers(id, name, setFlags);
return data;
}
My service class
export interface MetaFlags {
setServiceHeader: boolean
setCacheHeader?: boolean,
}
:
:
public async getUsers(....){
// code that handles whether cache is used or a service is used to get users
and based on it, the metaFlags are set. setCacheHeader = true if read from cache or setServiceHeader = true if read from DB.
My interceptor looks like this
@Injectable()
export class CacheOrServiceHeaderInterceptor implements NestInterceptor {
public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next
.handle()
.pipe(
map((data) => {
const req = context.switchToHttp().getRequest();
// this is static but I want a condition here if
if(MetaFlags.setCacheHeader)
// set xyz header
else set abc header
req.res.set('x-api-key', 'pretty secure');
return data;
}
)
);}}
Is there a way to pass these flags to the interceptor or make the interceptor read these flag values ?
Upvotes: 2
Views: 4985
Reputation: 70191
I would suggest returning what header should be set as a part of the service of controller's return. If you end up using a global state, you could get multiple requests to the endpoint overwriting the global state before you read it in the interceptor and send back the wrong header. Something like
{
data: regularDataHere,
header: 'cache' || 'database'
}
Now in the map
of your interceptor, you can read the data
object and pull off the data
property to return only it and not expose this header
field to the client, and read the header
field so you know which header to set on the response. Something like this:
@Injectable()
export class CacheOrServiceHeaderInterceptor implements NestInterceptor {
public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handler().pipe(
map((data: { data: DataType, header: 'cache' | 'database' }) => {
const res = context.switchToHttp().getResponse<ResponseType>();
if (data.header === 'database') {
res.setHeader('x-api-key', 'pretty secure');
} else {
res.setHeader(xyz, value);
}
return data.data;
})
);
}
}
Upvotes: 1