NestJSTypeScriptPostmanTutorial

NestJS to Postman without @nestjs/swagger

Generate a Postman collection from a NestJS app's controllers and class-validator DTOs, with global prefix, URI versioning and APP_GUARD auth handled. No Swagger decorators, no running app. Real output included.

The usual way to get a NestJS API into Postman is a detour through OpenAPI. You add @nestjs/swagger, decorate DTOs (or set up the CLI plugin), boot the app with its database and secrets, download /docs-json and import it. Then you write the token script yourself.

The DTOs, guards and controllers already contain everything Postman needs. routeman-cli reads them directly from the TypeScript source.

The app

A typical modern NestJS setup with a global prefix, URI versioning, a global JWT guard and a @Public() decorator for the open routes:

// main.ts
app.setGlobalPrefix('api');
app.enableVersioning({ type: VersioningType.URI, defaultVersion: '1' });
app.useGlobalPipes(new ValidationPipe({ whitelist: true }));

// app.module.ts
providers: [{ provide: APP_GUARD, useClass: JwtAuthGuard }]

// public.decorator.ts
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);

// product.dto.ts
export class CreateProductDto {
  @IsString() @Length(3, 120) name: string;
  @IsNumber() @Min(1) price: number;
  @IsEnum(Category) category: Category;
  @IsInt() @Min(0) @Max(10000) stock: number;
  @IsOptional() @IsString() description?: string;
}
export class UpdateProductDto extends PartialType(CreateProductDto) {}

The controllers have a public login, a protected /auth/me, and a products controller with public reads and protected writes, plus an image upload through FileInterceptor. See the NestJS guide for the full source.

Generate

$ npx routeman-cli
✓ nest: 8 requests (3 POST, 3 GET, 1 PATCH, 1 DELETE)
✓ auth: bearer (login: POST /api/v1/auth/login)
✓ wrote postman/nest-shop-api.postman_collection.json
✓ wrote postman/nest-shop-api.local.postman_environment.json
  done in 0.07s - import the files in Postman (File → Import)

$ npx routeman-cli routes
POST    /api/v1/auth/login             json: email, password
GET     /api/v1/auth/me              🔒
GET     /api/v1/products
POST    /api/v1/products             🔒 json: name, price, category, stock, description
DELETE  /api/v1/products/{id}        🔒
GET     /api/v1/products/{id}
PATCH   /api/v1/products/{id}        🔒 json: name, price, category, stock, description
POST    /api/v1/products/{id}/image  🔒 form: file
8 routes, auth: bearer (login: POST /api/v1/auth/login)

It took 0.07 seconds, with no nest build, no database and no Swagger module.

What it worked out

The full URL

setGlobalPrefix('api') plus defaultVersion: '1' with URI versioning gives /api/v1/… on every route. It is an easy detail to get wrong when writing NestJS requests by hand.

Which routes are public

The APP_GUARD provider protects everything, and the routes marked @Public() are exempt. routeman-cli sets the collection to Bearer auth and the three public routes (login, list products, get product) to No Auth, so Postman matches what the server will accept.

Bodies that pass the ValidationPipe

{
  "name": "John Doe",
  "price": 100,
  "category": "books",
  "stock": 1,
  "description": "Sample text"
}

@Length(3, 120), @Min(1) and @IsEnum(Category) are all satisfied. Every field sent is declared on the DTO, so whitelist: true has nothing to strip. The PATCH request uses the same fields from PartialType, all marked optional in the field table.

Names, parameters and uploads

  • The JSDoc comment on login() names the request Exchange email and password for an access token.
  • @Query('page') and @Query('q') become switched-off query parameters on List products.
  • ParseIntPipe makes {{productId}} an integer variable in the environment.
  • FileInterceptor('file') turns the upload into a form-data request with a file picker.
  • app.listen(3000) gives base_url = http://localhost:3000.

If you already use @nestjs/swagger

Keep it. Swagger UI is great for public docs. routeman-cli also reads @ApiProperty and @ApiOperation, so your descriptions carry over. If you'd rather build from the spec, run npx routeman-cli --openapi http://localhost:3000/docs-json. That still adds the login script, the environments and the smoke tests that a plain OpenAPI import lacks.

To make the result repeatable for the team, run npx routeman-cli init. It writes routeman.config.json, with a $schema for editor autocompletion.

Try routeman on your project

$ cd your-api
$ npx routeman-cli

Read the docs → Ask a question