'Versioning Nestjs routes?

I'm just getting started with Nestjs and am wondering how I can version my API using either a route prefix or through an Express Router instance?

Ideally, I would like to make endpoints accessible via:

/v1
/v2

etc, so I can gracefully degrade endpoints. I'm not seeing where I could add the version prefix. I know it's possible to set a global prefix on the application instance, but that's not for a particular set of endpoints.



Solution 1:[1]

Router Module comes to rescue, with Nest RouterModule it's now a painless organizing your routes.

See How it easy to setup.

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 {}

this will produce something like this:

ninja
    ??? /
    ??? /katana
    ??? cats
    ?   ??? /
    ?   ??? /ketty
    ??? dogs
        ??? /
        ??? /puppy

and sure, for Versioning the routes you could do similar to this

const routes: Routes = [
    {
      path: '/v1',
      children: [CatsModule, DogsModule],
    },
    {
      path: '/v2',
      children: [CatsModule2, DogsModule2],
    },
  ];

Nice !

check it out Nest Router

Solution 2:[2]

for version or any prefix, you can use "global prefix":

https://docs.nestjs.com/faq/global-prefix

Solution 3:[3]

Best and simple way to do this is using global prefix

An example is given below :

import { VersioningType } from "@nestjs/common";
     
app.enableVersioning({
        type: VersioningType.URI,
      });

      app.setGlobalPrefix("api/v1"); //edit your prefix as per your requirements!

You can exclude routes from the global prefix using the following construction:

app.setGlobalPrefix('v1', {
  exclude: [{ path: 'health', method: RequestMethod.GET }], // replace your endpoints in the place of health!
});

Alternatively, you can specify route as a string (it will apply to every request method):

app.setGlobalPrefix('v1', { exclude: ['cats'] }); // replace your endpoints in the place of cats!

Solution 4:[4]

according to latest docs inside main.ts after const app = await NestFactory.create(AppModule) use

  // Versioning
  app.enableVersioning({
    type: VersioningType.URI,
    defaultVersion: '1',
    prefix: 'api/v',
  });

This will give all your routes a default prefix of /api/v1 unless specified

To override version in controller use @Controller({version:'2'}) decorator on controller class

For overriding version at route level use @Version('2') above controller method

Note: If you are using swagger make sure to call app.enableVersioning() before SwaggerModule.createDocument()

Link: https://docs.nestjs.com/techniques/versioning

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Ziv
Solution 3
Solution 4 Ahmed Nawaz Khan