[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
When creating a resource, a restful api should return a 201 status code and a resource identifier (using location header) that points to the freshly created resource. We can set response status code via @HttpCode
decorator. But what about location header? Can we set location header without using @Res()
?
This is what I do right now:
@Post()
@HttpCode(HttpStatus.CREATED)
create(@Body() catDto: CatDto) : Observable<{}>{
return this.catService.create(catDto)
.map(() => Observable.empty())
.catch(error => this.httpExceptionService.mapToHttpExceptionObservable(error));
}
When I start using @Res()
the code turns into something like (express way):
@Post()
create(@Res() res, @Body() catDto: CatDto) {
this.catService.create(catDto)
.subscribe(cat => {
res.set('Location', cat.id);
res.status(HttpStatus.CREATED).send();
}, error => {
// create error response
});
}
I would like to do something like:
@Post()
@HttpCode(HttpStatus.CREATED)
create(@Body() catDto: CatDto) : Observable<{}>{
return this.catService.create(catDto)
.map(cat => {
// magically set location header here
return Observable.empty();
})
.catch(error => this.httpExceptionService.mapToHttpExceptionObservable(error));
}
I want to manipulate the response (i.p. the response headers) using standard (recommended) way and not express way.
Nest version: 4.5.6
For Tooling issues:
- Node version: 7.9.0
- Platform: Mac
Hi @ArtworkAD,
Inject request
instead of response
. request
has a res
property that is as response
in fact 馃檪
:1st_place_medal: @kamilmysliwiec awesome, this totally solves my problem. Thank you!
@artjomzab @kamilmysliwiec I have been trying this and it is not working in v5.6.2
import { Injectable, NestInterceptor, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Observable } from 'rxjs';
@Injectable()
export class MyInterceptor implements NestInterceptor {
private readonly customHeader = 'my-custom-header';
intercept(
context: ExecutionContext,
call$: Observable<any>,
): Observable<any> {
const request = context.switchToHttp().getRequest();
request.res.header[this.customHeader] = 'foo';
return call$;
}
}
results in
TypeError: Cannot read property 'header' of undefined
at MyInterceptor.intercept (my.interceptor.ts:30:19)
at interceptors.reduce (node_modules/@nestjs/core/interceptors/interceptors-consumer.js:22:95)
What's the proper way to add custom response headers from an interceptor?
Hi @ArtworkAD,
Injectrequest
instead ofresponse
.request
has ares
property that is asresponse
in fact 馃檪
So this is recommended way of appending data to response body?
@felangel
@artjomzab @kamilmysliwiec I have been trying this and it is not working in v5.6.2
import { Injectable, NestInterceptor, ExecutionContext } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { Observable } from 'rxjs'; @Injectable() export class MyInterceptor implements NestInterceptor { private readonly customHeader = 'my-custom-header'; intercept( context: ExecutionContext, call$: Observable<any>, ): Observable<any> { const request = context.switchToHttp().getRequest(); request.res.header[this.customHeader] = 'foo'; return call$; } }
results in
TypeError: Cannot read property 'header' of undefined at MyInterceptor.intercept (my.interceptor.ts:30:19) at interceptors.reduce (node_modules/@nestjs/core/interceptors/interceptors-consumer.js:22:95)
What's the proper way to add custom response headers from an interceptor?
What I'm doing is the same, but inside call$.pipe(map())
, like the following.
@Injectable()
export class MyInterceptor implements NestInterceptor {
private readonly customHeader = 'my-custom-header';
intercept(
context: ExecutionContext,
call$: Observable<any>,
): Observable<any> {
call$.pipe(map(data => {
const request = context.switchToHttp().getRequest();
request.res.header[this.customHeader] = 'foo';
return data;
}));
}
}
However, this now fails downstream with Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
.
UPDATE: @felangel Your case is solved if you use request.res.set(this.customHeader, 'foo')
. However, I'm not sure how to edit response header as observed after execution, before returning. So we can, for instance, replace something in it.
Just use .getResponse()
instead of .getRequest()
.
Just use
.getResponse()
instead of.getRequest()
.
@kamilmysliwiec Does this actually work?
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
Hi @ArtworkAD,
Inject
request
instead ofresponse
.request
has ares
property that is asresponse
in fact 馃檪