nest-router icon indicating copy to clipboard operation
nest-router copied to clipboard

Defining routes as both nested and top level

Open danielcornock opened this issue 5 years ago • 3 comments

In my application I have an entity 'stories', that I want to be able to reach from the top level of routes (e.g. api/v1/stories) but also to access it nested so that it can have parameters for another entity, e.g. api/v1/boards/:boardId/stories.

Is this possible with the current build? I've tried out different ways of organising them but it seems that multiple declarations of a module will overwrite any previous ones.

For example one setup that I tried was:

const routes: Routes = [
  {
    path: '/stories',
    module: StoryModule
  },
  {
    path: '/boards',
    module: BoardModule,
    children: [
      {
        path: '/:boardId/stories',
        module: StoryModule
      }
    ]
  }
];

In this case the boards route and nested stories route works, but the top level stories route does not. If i place the top level stories route after the nested route, that one works and the nested one doesn't.

danielcornock avatar Jan 03 '20 14:01 danielcornock

well, in this case, I'd recommend using regex to match both paths, since I think that the only way we can do it since Nestjs is already supporting path regex: The best regex here should be: ^boards\/(?:([^\/]+?))\/stories|^stories(?=\/|$)

I know it seems complicated, but can we do better?

See it in action here: https://regex101.com/r/R7IxYM/2

this is helpful too: http://forbeslindesay.github.io/express-route-tester/

shekohex avatar Jan 03 '20 15:01 shekohex

I ran into a similar issue and I got around it by doing a bit more leg work. What you could do for the time being is create a new Module called BoardStoryModule and extend your story module, then import the BoardStoryModule into your routing document and use it.

frankmoto avatar Jan 09 '20 19:01 frankmoto

We have a similar issue, with dynamic modules.

When trying to setup the router on two different modules utilising the same shared module dynamically initialised.

Setup as follows:

const AnimalModuleInstance1: DynamicModule = {
    module: SharedModuleWithRoutes,
};

const AnimalModuleInstance2: DynamicModule = {
    module: SharedModuleWithRoutes,
};

const DOG_ROUTES: Routes = [
    {
        path: '/1/',
        module: DogModule,
        children: [
            AnimalModuleInstance1.module,
        ]
    }
];

const CAT_ROUTES: Routes = [
    {
        path: '/2/',
        module: CatModule,
        children: [
            AnimalModuleInstance2.module,
        ]
    }
];

We run into issues as the router module tries to reference the module based on the nestModule.metatype which will be "SharedModuleWithRoutes" https://github.com/nestjsx/nest-router/blob/f7b2374e89f04ddf99c2a94e4edb30f6a41a0dcd/src/router.module.ts#L20

setting the base path to either /2/ or /1/ to both modules depending on which module is initialised last.

changing the reflector to use the module object reference rather than the metatype seems to resolve our issue - however will not work if string based module references are allowed in children property interface.

- const modulePath: string = Reflect.getMetadata(MODULE_PATH, nestModule.metatype);
+ const modulePath: string = Reflect.getMetadata(MODULE_PATH, nestModule);

Discountrobot avatar Jun 03 '21 15:06 Discountrobot