How to create nested routes with parameters using NestJS
Solution 1
Regarding your use case, you might want to take a look at this router module
=> https://github.com/shekohex/nest-router
Following the documentation of this module, you can define your routes like so:
... //imports
const routes: Routes = [
{
path: '/ninja',
module: NinjaModule,
children: [
{
path: '/cats',
module: CatsModule,
},
{
path: '/dogs',
module: DogsModule,
},
],
},
];
@Module({
imports: [
RouterModule.forRoutes(routes), // setup the routes
CatsModule,
DogsModule,
NinjaModule
], // as usual, nothing new
})
export class ApplicationModule {}
Of course, the routes would be defined in a separate file like routes.ts
Given the fact you have a controller by module, the previous code would end in the following tree of routes:
ninja
├── /
├── /katana
├── cats
│ ├── /
│ └── /ketty
├── dogs
├── /
└── /puppy
Example:
If you want to reach the ketty
controller's routes, you will need to reach this endpoint:
<your-api-host>/ninja/cats/ketty
Update
This approach is outdated today if you using NestJs v8.0.0
or later, as the documentation of nest-router tells us it's now included on @nestjs/core
and also as pointed by @yehonatan yehezkel, you can follow the documentation for the recommended approach at here https://docs.nestjs.com/recipes/router-module
Solution 2
i think you need this?
import {Controller, Get, Param} from "@nestjs/common";
@Controller('accounts/:account')
export class TestController{
@Get('resource2/:someParam/whatever')
arsPW(@Param('account') account, @Param('someParam') someparam){
console.log(':account/resource2/:someParam/whatever',account,someparam)
return account+'_'+someparam+'___';
}
@Get('resource1/:someparam')
aRSP(@Param('account') account, @Param('someparam') someparam){
console.log(':account/resource1/:someParam',account,someparam)
return account+'_'+someparam;
}
@Get()
getget(){
console.log('get');
return 'aaa';
}
}
Solution 3
Parent controller :
@Controller('accounts')
export class AccountsController {
// http://api.domaine.com/accounts
@Get()
Child controller :
@Controller('accounts/:id')
export class ResourcesController {
// http://api.domaine.com/accounts/1/resources
@Get('resources')
Solution 4
you can simply do this
@Controller('trainer/:trainerId/heroes')
export class HeroesController {
constructor(private readonly heroesService: HeroesService) {}
@Get(':id')
findOne(@Param('trainerId') trainerId:string,@Param('id') id: string) {
return `This action returns a #${id} hero trainer id ${trainerId}`;
}
}
the uri is:
http://localhost:3000/trainer/4/heroes/5
thr result is
This action returns a #5 hero trainer id 4
Related videos on Youtube
Comments
-
Francesco Borzi over 2 years
I need to build an API where most of the routes are prefixed with a common URL part which also has a parameter.
In my specific case, my routes need to look like:
/accounts/:account/resource1/:someParam
/accounts/:account/resource2/:someParam/whatever
/accounts/:account/resource3/
/accounts/:account/resource4/subResource/
and so on..
So ideally I would create a parent route
/accounts/:account/
which will contain the children routes (resource1
,resource2
,resource3
,resource4
, etc...).I also need the
:account
parameter to be accessible from all the children routes.What is the best way to achieve this with NestJS ?
-
Muhammad Usman almost 6 years
-
-
Francesco Borzi almost 6 yearsthis is what I'm currently using, but what if I have many children routes? I don't want to have a single, fat Controller class. Ideally I would be able to create different child routes inside different Controller classes
-
Ambroise Rabier about 5 yearsI think this do not answer this requirement "I also need the :account parameter to be accessible from all the children routes.".
-
Maxime Lechevallier about 4 yearsCheck out the part about nested route: github.com/nestjsx/nest-router#params-in-nested-routes
-
Paweł Lubczyński over 3 years...and then how you get :id from that second example?
-
Yu Yenkan over 3 yearsmethod(@param('id') id)
-
mikey almost 3 yearsThis is the pattern I'm using, and it's the best I've seen, but it's still not great for an enterprise API. If you then want to have
/resources/:id
, you need to define anotherResourcesController
, perhaps renaming the one above toAccountsResourcesController
to make 'space'. I wish there were a mechanism to annotate a class method to ignore the parent controller route / override it. If anyone spots this and finds a better way, please let me know! -
yehonatan yehezkel over 2 yearsthis way is not recommended by nestjs docs because it became to complex to mantain docs.nestjs.com/recipes/router-module
-
Jayna Tanawala about 2 yearsI have kind of the same controller file. But I am not able to call this API. Am I missing something?