How to create nested routes with parameters using NestJS

29,871

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
Share:
29,871

Related videos on Youtube

Francesco Borzi
Author by

Francesco Borzi

https://github.com/FrancescoBorzi

Updated on January 14, 2022

Comments

  • Francesco Borzi
    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 ?

  • Francesco Borzi
    Francesco Borzi almost 6 years
    this 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
    Ambroise Rabier about 5 years
    I think this do not answer this requirement "I also need the :account parameter to be accessible from all the children routes.".
  • Maxime Lechevallier
    Maxime Lechevallier about 4 years
    Check out the part about nested route: github.com/nestjsx/nest-router#params-in-nested-routes
  • Paweł Lubczyński
    Paweł Lubczyński over 3 years
    ...and then how you get :id from that second example?
  • Yu Yenkan
    Yu Yenkan over 3 years
    method(@param('id') id)
  • mikey
    mikey almost 3 years
    This 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 another ResourcesController, perhaps renaming the one above to AccountsResourcesController 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
    yehonatan yehezkel over 2 years
    this way is not recommended by nestjs docs because it became to complex to mantain docs.nestjs.com/recipes/router-module
  • Jayna Tanawala
    Jayna Tanawala about 2 years
    I have kind of the same controller file. But I am not able to call this API. Am I missing something?