I am pretty new to this kind of stuff so any advice is appreciated, especially if there's a better way to solve this than what I am looking for.
I am trying to support an old endpoint by redirecting it to a new endpoint, and both endpoints should support query parameters. Each endpoint lives in a separate controller.
Example:
I want /old-namespace/getStuff?foo=bar
to redirect to /new-namespace/getStuff?foo=bar
without manually rebuilding a query string like the Nest docs point out, because the params can be dynamic.
Looking at the NestJS docs, there is a handy @Redirect
decorator that you can use on an endpoint like so, to easily redirect the request to a different URL:
@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
if (version && version === '5') {
return { url: 'https://docs.nestjs.com/v5/' };
}
}
However, when using this, request.query
is cleared on redirect (pretty sure this is expected behavior). Does anyone have a minimally-invasive solution for this? I've tested out building middleware/interceptors/custom decorators to get around this with varying degrees of success, but that seems heavy-handed and I wish there was a way to throw an extra param in the @Redirect
decorator like retainQuery = true
or something.
CodePudding user response:
I ended up using the top answer here: How to rewrite url path in Nestjs?
Ambroise Rabier's first response on nginx rewrites cued me in to search for a simple middleware solution since I didn't want to inject a service in multiple places, as there will be quite a few small redirects from old namespaces to new ones.
In a common module:
consumer
.apply(RewriteApiEndpointMiddleware)
.forRoutes('/')
In a middleware:
import { Injectable, NestMiddleware } from '@nestjs/common';
@Injectable()
export class RewriteApiEndpointMiddleware implements NestMiddleware {
use(req: any, res: any, next: () => void) {
// the linked answer replaced "api" but in my case I needed to send "app" requests somewhere else
req.url = req.url.replace(/^\/app/, '/new-namespace');
next();
}
}
CodePudding user response:
What you need is called rewrite in nginx.
I don't know if it work, but maybe you can do that ?
@Get('/old-namespace/getStuff')
getStuff(@Query() query) {
// Done !
getNewStuff(query);
}
@Get('/new-namespace/getStuff')
getNewStuff(@Query() query) {
}
If not, you can always do something like:
function handleGetNewStuff() {
}
@Get('/old-namespace/getStuff')
getStuff(@Query() query) {
handleGetNewStuff(query);
}
@Get('/new-namespace/getStuff')
getNewStuff(@Query() query) {
handleGetNewStuff(query);
}
However, if your issue is about changing the link on the user side (and not just for internal routing), you can try (not tested either):
@Get('/old-namespace/getStuff')
getStuff(@Req() request, @Res() response) {
const newURL = req.originalUrl.replace('old', 'new');
response.redirect(newURL);
}
Remember that NestJS use expressJS bellow.