#@nestjs/swagger. How to split swagger docs into 2 documents: for clients and admins

6 messages · Page 1 of 1 (latest)

manic scarab
#

I'm using NestJS (v11) and @nestjs/swagger (v11.0.3).

I have a modular app structure where some controllers are intended for public clients (mobile app, frontend) and others are intended for admin dashboard usage.

Problem: When I generate the Swagger documentation using SwaggerModule.createDocument(), it includes all controllers from a module. I want to split Swagger into two separate documents:

/docs → for Public API (client)

/docs-admin → for Admin API

My current swagger setup (main.ts):

    .setTitle('API')
    .setDescription('API Documentation')
    .addServer(`${baseUrl}/${apiPrefix}`)
    .setVersion('1.0')
    .build();

  const document = SwaggerModule.createDocument(app, config);

  SwaggerModule.setup('docs', app, document, {
    swaggerOptions: {
      search: true,
    },
  });```

App.module.ts
```@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    CacheModule.register({
      isGlobal: true,
    }),
    TypeOrmModule.forRootAsync({
      inject: [ConfigService],
      useFactory: createTypeOrmConfig,
    }),
    ApiModule,
  ],
})
export class AppModule {}```

api.module.ts
```@Module({
  imports: [AuthModule, GamesDomainModule, HealthModule, MarketplaceDomainModule],
})
export class ApiModule {}```

marketplace-domain.module.ts
```@Module({
  imports: [PerkProvidersModule, PerksModule],
})
export class MarketplaceDomainModule {}```

perks.module.ts
```@Module({
  imports: [TypeOrmModule.forFeature([Perk]), PerkProvidersModule],
  providers: [PerksService],
  controllers: [PerksController, AdminPerksController],
})
export class PerksModule {}```

The problem is that in controllers array I define both PerksController and AdminPerksController. So I cannot just pass in swagger configuration:
`include: [PerksModule]`

What are best approaches here? Should I split modules completely (e.g., create PerksModule and PerksAdminModule) just to separate Swagger documents?
#

Client (Public) Controller definition:

@UseGuards(JwtAuthGuard)
@Controller('perks')
export class PerksController {}```

Admin Controller definition
```@ApiTags('[ADMIN] Marketplace.Perks')
@UseGuards(JwtAuthGuard, RoleGuard)
@RequireRole(UserRole.ADMIN)
@Controller('admin/perks')```
supple hamlet
#

The document created by using the swagger module, that is an object up to OpenAPI spec. You can modify it before serving or saving to file.
You can filter out all paths that contain [ADMIN] in the tag.

manic scarab
#

@supple hamlet this solution seems too complicated. I’ve already tried it. Because we need to filter not only paths but schemas, security schemas etc. I am trying to find more simple solution based on modules

supple hamlet
manic scarab
#

@supple hamlet

  imports: [TypeOrmModule.forFeature([Perk]), PerkProvidersModule],
  providers: [PerksService],
  controllers: [PerksController, AdminPerksController],
})
export class PerksModule {}```

How to reuse shared logic (imports and providers] between 2 modules? Create SharedModule?

And do something like:
```@Module({
  imports: [SharedModule]
  controllers: [PerksController],
})
export class PerksModule {}```

```@Module({
  imports: [SharedModule],
  controllers: [AdminPerksController],
})
export class AdminPerksModule {}```

What do you think?