OpenAPI Documentation Guide
This guide explains how to use and maintain the OpenAPI documentation for the LandlordX API.
Overview
The LandlordX API uses @nestjs/swagger to automatically generate OpenAPI 3.1 specifications from TypeScript decorators. The documentation is:
- Auto-generated on server start
- Available via Stoplight Elements UI at
/api-docs - Exported to
/apim/openapi.yamlfor use with Stoplight Studio
Quick Start
Viewing API Documentation
-
Start the development server:
pnpm start:dev:backend -
Open your browser and navigate to:
http://localhost:5500/api-docs -
The Stoplight Elements UI provides an interactive interface to explore and test all API endpoints.
Generated Files
When the server starts, two files are automatically generated in the /apim directory:
openapi.yaml- YAML format (for Stoplight Studio)openapi.json- JSON format (for programmatic access)
Generate Without Starting the Server
You can generate the OpenAPI specs without binding a port or starting the HTTP server:
pnpm --filter api-app openapi:genThis compiles the API and emits apim/openapi.yaml and apim/openapi.json by creating a Nest application context with a mocked database connection.
Using with Stoplight Studio
Stoplight Studio is a free visual OpenAPI editor that can be used to view, edit, and mock your API.
Installation
- Download Stoplight Studio from https://stoplight.io/studio
- Install and launch the application
Opening the Project
- In Stoplight Studio, click “Open Existing Folder”
- Navigate to the repository root
- The
/apim/openapi.yamlfile will be automatically detected
Workflow
-
Start the API server to generate fresh OpenAPI specs:
pnpm start:dev:backend -
Open Stoplight Studio and navigate to the
apimfolder -
View and edit the OpenAPI spec visually
-
Generate mock servers using Stoplight’s Prism integration
-
Publish documentation to Stoplight Platform (optional)
Adding API Documentation
Controller Decorators
Use @ApiTags to group endpoints:
import {
ApiTags,
ApiBearerAuth,
ApiOperation,
ApiResponse,
} from "@nestjs/swagger";
@ApiTags("Properties")
@ApiBearerAuth("JWT-auth")
@Controller("properties")
@UseGuards(JwtAuthGuard)
export class PropertyController {
// ...
}Endpoint Decorators
Document each endpoint with operation and response decorators:
@Get(":id")
@ApiOperation({
summary: "Get a property by ID",
description: "Retrieve a single property by its ID. Requires authentication.",
})
@ApiParam({
name: "id",
type: "number",
description: "Property ID",
example: 1,
})
@ApiResponse({
status: 200,
description: "Property retrieved successfully",
schema: {
type: "object",
properties: {
message: { type: "string", example: "Property retrieved successfully" },
data: { type: "object" },
},
},
})
@ApiResponse({
status: 401,
description: "Unauthorized - Invalid or missing JWT token",
})
@ApiResponse({
status: 404,
description: "Property not found",
})
async findOne(@Param("id", ParseIntPipe) id: number) {
// ...
}DTO Decorators
Document request/response DTOs with property decorators:
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
export class CreatePropertyDto {
@ApiProperty({
description: "Alias name for the property",
example: "My Koramangala House",
})
@IsNotEmpty()
@IsString()
alias_name: string;
@ApiPropertyOptional({
description: "Nearby landmark",
example: "Near Forum Mall",
})
@IsOptional()
@IsString()
landmark?: string;
}For Update DTOs
Use Swagger’s PartialType to inherit documentation from create DTOs:
import { PartialType } from "@nestjs/swagger";
export class UpdatePropertyDto extends PartialType(CreatePropertyDto) {}Authentication Documentation
The API uses JWT Bearer token authentication. The security scheme is defined in main.ts:
.addBearerAuth(
{
type: "http",
scheme: "bearer",
bearerFormat: "JWT",
name: "Authorization",
description: "Enter your Supabase JWT token",
in: "header",
},
"JWT-auth"
)Protected endpoints use @ApiBearerAuth("JWT-auth") decorator.
Excluding Endpoints
To exclude endpoints from the documentation:
import { ApiExcludeController, ApiExcludeEndpoint } from "@nestjs/swagger";
// Exclude entire controller
@ApiExcludeController()
@Controller()
export class AppController {}
// Or exclude specific endpoint
@Get()
@ApiExcludeEndpoint()
healthCheck() {}Publishing Documentation
Static Hosting
The generated openapi.yaml can be hosted statically and viewed with:
Stoplight Platform
- Create an account at https://stoplight.io
- Create a new project
- Import the
/apim/openapi.yamlfile - Publish to get a hosted documentation URL
Best Practices
- Keep documentation in sync - Always update decorators when changing API behavior
- Use meaningful examples - Provide realistic example values in
@ApiProperty - Document error responses - Include all possible error status codes
- Group related endpoints - Use consistent
@ApiTagsacross related controllers - Version your API - Consider adding version prefix when needed
Troubleshooting
Documentation not updating
Make sure to restart the server after making changes to decorators:
# Kill the running server and restart
pnpm start:dev:backendMissing schemas
Ensure all DTOs use @ApiProperty or @ApiPropertyOptional decorators on each property.
Type issues with PartialType
Import PartialType from @nestjs/swagger instead of @nestjs/mapped-types:
import { PartialType } from "@nestjs/swagger"; // ✅ Correct
import { PartialType } from "@nestjs/mapped-types"; // ❌ Won't include schema info