[ ] 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,
Injectrequestinstead ofresponse.requesthas aresproperty that is asresponsein 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
requestinstead ofresponse.requesthas aresproperty that is asresponsein fact 馃檪