#RouterModule: Share same module under two different routes in NestJs

37 messages · Page 1 of 1 (latest)

violet dock
#

Context: I have the following modules in my nestjs app. Which have just the boilerplate code. These modules were generated using command nest g resource resourceName.

  1. CatModule
  2. DogModule
  3. FoodModule

Issue: Nestjs is not allowing to share the FoodModule for two distinct routes. I was under the impression that it can be achieved using RouterModule.register(). But nestjs is only registering the routes /food for DogModule and not for CatModule.

New Understanding: Which ever module comes last in the RouterModule is able to have /food routes

Outcome: I want to achieve the following routing:

/cats/food
/dogs/food
Such that both /cats and /dogs route can access /food routes.

Code: I have use the below code to try achieve my outcome but it doesn't work:

  • app.module.ts

    
    @Module({
      imports: [
        CatsModule,
        DogsModule,
        FoodModule,
    
        RouterModule.register([
          {
            path: "cats",
            module: CatsModule,
            children: [
              {
                path: "/food",
                module: FoodModule,
              },
            ],
          },
          {
            path: "dogs",
            module: DogsModule,
            children: [
              {
                path: "/food",
                module: FoodModule,
              },
            ],
          },
        ]),
      ],
      controllers: [AppController],
      providers: [AppService],
    })
    export class AppModule {}
    
  • cats.module.ts

    @Module({
      imports: [FoodModule],
      controllers: [CatsController],
      providers: [CatsService],
    })
    export class CatsModule {}
    
  • dogs.module.ts

    @Module({
      imports: [FoodModule],
      controllers: [DogsController],
      providers: [DogsService],
    })
    export class DogsModule {}
    
  • Attached logs in screenshot which show the routes.

violet dock
#

RouterModule: Share same module under two different routes in NestJs

empty horizonBOT
#

Please do not tag the moderators unless someone is breaking server rules. The mods are here to help enforce the rules of the server, and while most of them are knowledgeable about Nest, they are not the only ones able to solve your question.

sterile sierra
#

Honestly, I have no idea. But likely it's not possible. I've used router module in the past, but found it a little too restrictive to my liking

#

So now I always define the full path in the controller decorator, which is IMO more maintainable in the long term, because you can immediately see the whole path and don't have to click through multiple files just to find out which route that handler serves

violet dock
#

So, as of now my workaround is that I had add same routes inside food.controller.ts to cat.controller.ts and call food.service.ts when a call comes to cat/food/:id

violet dock
sterile sierra
#

I would ditch the router module altogether

#

And I would also try my best to avoid having a single handler available on multiple paths

#

But that's an API design question, not a technical one

#

Why does the food module be nested under the animal, when you're getting food by id? It doesn't matter if it's for a cat or a dog

#

Or, if it does, you need two modules, one for cat food and the second for dog food

violet dock
#

REST convenstions

sterile sierra
#

Is the food resource a child of a dog or cat resources?

#

Or is it it's own resource?

#

I would say the latter, which align sith rest conventions better I think

violet dock
#

In my codebase food is a module which is a resource of its own. think of it only admins can add food which can be consumed by cat and dog.

#

So in dashboard if I have to showcase all the food available for a particular cat in my understanding /cats/:catId/foods/ will be a better path no?

sterile sierra
#

What is the relationship there? Should dog or cat know about the food resource?

Or is it inverse? So, the food should know if it is for dog or cat?

#

If it's the latter, a better structure might be /foods?animal=cat&animalId=1234

#

And /foods/:foodId for a single food item

#

But of course, you know your application and it's uses better than me, so only take this as inspiration

violet dock
#

But the thing is how would you ever represent a sub resource/nested resource?

sterile sierra
#

Often, it's better to keep the structure as flat as possible, becuase nested structures become inflexibe very fast

sterile sierra
#

But neither dog nor cat owns the food resource in this situation, they merely access it