@nestjsvn/swagger-sse
Version:
OpenAPI documentation and interactive Swagger UI for NestJS Server-Sent Events endpoints
523 lines (373 loc) • 11.8 kB
Markdown
# API Reference
Complete reference for all `@nestjsvn/swagger-sse` APIs, interfaces, and configuration options.
## Table of Contents
1. [Decorators](#decorators)
2. [Interfaces](#interfaces)
3. [Functions](#functions)
4. [Plugin Configuration](#plugin-configuration)
5. [UI Components](#ui-components)
6. [Type Definitions](#type-definitions)
## Decorators
### @ApiSse
The main decorator for documenting Server-Sent Events endpoints.
```typescript
@ApiSse(options: ApiSseOptions): MethodDecorator
```
#### Parameters
- `options` - Configuration object of type [`ApiSseOptions`](#apisseoptionsinterface)
#### Features
- **Automatic Model Registration**: The decorator automatically registers all model types from the `events` parameter using `@ApiExtraModels`, eliminating the need for manual registration
- **Type Safety**: Full TypeScript support with compile-time type checking
- **Schema Generation**: Automatically generates OpenAPI schemas with oneOf/discriminator patterns
#### Example
```typescript
@ApiSse({
summary: 'User events stream',
description: 'Real-time stream of user-related events',
events: {
'user-created': UserCreatedDto, // Automatically registered with @ApiExtraModels
'user-updated': UserUpdatedDto, // Automatically registered with @ApiExtraModels
},
tags: ['users', 'events'],
deprecated: false,
})
@Sse('user-stream')
streamUserEvents(): Observable<MessageEvent> {
// Implementation
}
```
> **Note**: You no longer need to manually add `@ApiExtraModels(UserCreatedDto, UserUpdatedDto)` to your controller or method. The `@ApiSse` decorator handles this automatically.
## Interfaces
### ApiSseOptions Interface
Configuration options for the `@ApiSse` decorator.
```typescript
interface ApiSseOptions {
/** Map of event names to their corresponding DTO types */
events: { [eventName: string]: Type<unknown> | Function | [Function] | string };
/** Default event type for messages without explicit event name */
defaultEvent?: Type<unknown> | Function | [Function] | string;
/** Response content type (defaults to 'text/event-stream') */
produces?: string;
/** Short summary of the operation */
summary?: string;
/** Detailed description of the operation */
description?: string;
/** Unique operation identifier */
operationId?: string;
/** Tags for grouping operations */
tags?: string[];
/** Mark operation as deprecated */
deprecated?: boolean;
/** Security requirements for the operation */
security?: SecurityRequirementObject[];
}
```
#### Properties
##### events (required)
Maps event names to their corresponding TypeScript types or DTO classes.
**Type**: `{ [eventName: string]: Type<unknown> | Function | [Function] | string }`
**Examples**:
```typescript
// Using DTO classes
events: {
'user-created': UserCreatedDto,
'user-updated': UserUpdatedDto,
}
// Using inline types
events: {
'simple-event': { message: string },
'complex-event': ComplexEventDto,
}
// Using arrays for array types
events: {
'batch-update': [UserDto],
}
```
##### defaultEvent (optional)
Default event type for messages that don't specify an event type.
**Type**: `Type<unknown> | Function | [Function] | string`
**Example**:
```typescript
defaultEvent: GenericEventDto
```
##### produces (optional)
Response content type. Defaults to `'text/event-stream'`.
**Type**: `string`
**Default**: `'text/event-stream'`
##### summary (optional)
Short summary of the SSE endpoint operation.
**Type**: `string`
##### description (optional)
Detailed description of the SSE endpoint operation.
**Type**: `string`
##### operationId (optional)
Unique identifier for the operation. Used by code generators.
**Type**: `string`
##### tags (optional)
Array of tags for grouping operations in Swagger UI.
**Type**: `string[]`
##### deprecated (optional)
Mark the operation as deprecated.
**Type**: `boolean`
**Default**: `false`
##### security (optional)
Security requirements for the operation.
**Type**: `SecurityRequirementObject[]`
**Example**:
```typescript
security: [{ bearer: [] }]
```
### SsePluginOptions Interface
Configuration options for the CLI plugin.
```typescript
interface SsePluginOptions {
/** Event naming convention for auto-generated event names */
eventNamingConvention?: 'kebab-case' | 'camelCase' | 'PascalCase';
/** Whether to introspect JSDoc comments for documentation */
introspectComments?: boolean;
/** Whether to auto-generate operation IDs */
autoGenerateOperationId?: boolean;
/** Custom event type mappings */
customEventMappings?: { [typeName: string]: string };
}
```
#### Properties
##### eventNamingConvention (optional)
Convention for auto-generated event names from TypeScript types.
**Type**: `'kebab-case' | 'camelCase' | 'PascalCase'`
**Default**: `'kebab-case'`
**Examples**:
- `'kebab-case'`: `UserCreatedDto` → `'user-created'`
- `'camelCase'`: `UserCreatedDto` → `'userCreated'`
- `'PascalCase'`: `UserCreatedDto` → `'UserCreated'`
##### introspectComments (optional)
Whether to extract documentation from JSDoc comments.
**Type**: `boolean`
**Default**: `true`
##### autoGenerateOperationId (optional)
Whether to automatically generate operation IDs.
**Type**: `boolean`
**Default**: `false`
##### customEventMappings (optional)
Custom mappings from TypeScript type names to event names.
**Type**: `{ [typeName: string]: string }`
**Example**:
```typescript
customEventMappings: {
'UserCreatedDto': 'user.created',
'OrderProcessedDto': 'order.processed',
}
```
## Functions
### setupSsePlugin
Sets up Swagger UI with SSE plugin support.
```typescript
function setupSsePlugin(
app: INestApplication,
document: OpenAPIObject,
path: string,
options?: SwaggerCustomOptions
): void
```
#### Parameters
- `app` - NestJS application instance
- `document` - OpenAPI document generated by SwaggerModule
- `path` - Path where Swagger UI will be served
- `options` - Optional Swagger UI customization options
#### Example
```typescript
import { setupSsePlugin } from '@nestjsvn/swagger-sse';
const document = SwaggerModule.createDocument(app, config);
setupSsePlugin(app, document, 'api-docs', {
customSiteTitle: 'My API Documentation',
customCss: '.swagger-ui .topbar { display: none }',
});
```
### generateSseSchema
Generates OpenAPI schema for SSE events (internal function).
```typescript
function generateSseSchema(options: ApiSseOptions): SchemaObject
```
#### Parameters
- `options` - SSE configuration options
#### Returns
OpenAPI schema object with oneOf/discriminator pattern for event types.
## Plugin Configuration
### nest-cli.json Configuration
Configure the CLI plugin in your `nest-cli.json` file:
```json
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true,
"plugins": [
"@nestjs/swagger",
{
"name": "@nestjsvn/swagger-sse/plugin",
"options": {
"eventNamingConvention": "kebab-case",
"introspectComments": true,
"autoGenerateOperationId": false,
"customEventMappings": {
"UserCreatedDto": "user.created"
}
}
}
]
}
}
```
### Plugin Behavior
The CLI plugin automatically:
1. **Detects SSE endpoints** decorated with `@Sse()`
2. **Analyzes return types** to extract event types from `Observable<MessageEvent<T>>`
3. **Generates event mappings** based on TypeScript union types
4. **Adds @ApiSse decorators** with inferred configuration
5. **Extracts JSDoc comments** for documentation
## UI Components
### SSE Connection Interface
The Swagger UI plugin adds these interactive elements:
#### Connection Controls
- **Connect Button**: Establishes SSE connection
- **Disconnect Button**: Closes SSE connection
- **Status Indicator**: Shows connection state (connected/disconnected/error)
#### Event Display
- **Event Log**: Scrollable list of received events
- **Event Filtering**: Filter events by type
- **Clear Button**: Clear event history
- **Timestamp Display**: Shows when each event was received
#### Event Format
Events are displayed with:
- **Event Type**: The event name/type
- **Timestamp**: When the event was received
- **Data**: JSON-formatted event payload
- **Raw Data**: Toggle to show raw event data
### CSS Classes
The plugin adds these CSS classes for styling:
```css
.sse-plugin-container { /* Main container */ }
.sse-connection-controls { /* Connection buttons area */ }
.sse-status-indicator { /* Connection status */ }
.sse-event-log { /* Event log container */ }
.sse-event-item { /* Individual event */ }
.sse-event-type { /* Event type label */ }
.sse-event-timestamp { /* Event timestamp */ }
.sse-event-data { /* Event data content */ }
```
## Type Definitions
### MessageEvent Extension
The library extends the standard MessageEvent interface:
```typescript
interface MessageEvent<T = any> {
data: string; // JSON stringified event data
type: string; // Event type name
lastEventId?: string;
origin?: string;
ports?: MessagePort[];
source?: EventSource;
}
```
### Event Schema Types
```typescript
type EventTypeMapping = {
[eventName: string]: Type<unknown> | Function | [Function] | string;
};
type EventSchema = {
oneOf: SchemaObject[];
discriminator: {
propertyName: string;
mapping: { [eventName: string]: string };
};
};
```
### Plugin Types
```typescript
type EventNamingConvention = 'kebab-case' | 'camelCase' | 'PascalCase';
type CustomEventMapping = {
[typeName: string]: string;
};
```
## Error Handling
### Common Error Types
#### SSE Connection Errors
```typescript
interface SseConnectionError {
type: 'connection_error';
message: string;
code?: number;
timestamp: Date;
}
```
#### Schema Generation Errors
```typescript
interface SchemaGenerationError {
type: 'schema_error';
message: string;
context: {
eventName: string;
eventType: string;
};
}
```
#### Plugin Transformation Errors
```typescript
interface PluginError {
type: 'plugin_error';
message: string;
file: string;
line: number;
}
```
## Best Practices
### Event Naming
- Use consistent naming conventions
- Prefer kebab-case for event names
- Use descriptive, action-oriented names
- Group related events with prefixes
```typescript
// Good
events: {
'user-created': UserCreatedDto,
'user-updated': UserUpdatedDto,
'user-deleted': UserDeletedDto,
}
// Avoid
events: {
'user1': UserDto,
'userStuff': UserDto,
'u_created': UserDto,
}
```
### Type Safety
- Always use TypeScript classes or interfaces for event types
- Avoid `any` types in event definitions
- Use union types for complex event scenarios
```typescript
// Good
type UserEvent =
| { type: 'created'; data: UserCreatedDto }
| { type: 'updated'; data: UserUpdatedDto };
// Avoid
events: {
'user-event': any,
}
```
### Performance
- Limit event log size in UI
- Use event filtering for high-frequency streams
- Implement proper error handling
- Consider connection cleanup on component unmount
## Migration Guide
### From Standard SSE
If you're migrating from standard NestJS SSE endpoints:
1. **Add the package**: `npm install @nestjsvn/swagger-sse`
2. **Replace setup**: Use `setupSsePlugin()` instead of `SwaggerModule.setup()`
3. **Add decorators**: Add `@ApiSse()` to your SSE endpoints
4. **Update types**: Ensure your DTOs are properly typed
5. **Test documentation**: Verify Swagger UI shows SSE interfaces
### Version Compatibility
- **NestJS**: v9.0.0+ (v10.0.0+ recommended)
- **@nestjs/swagger**: v6.0.0+ (v7.0.0+ recommended)
- **TypeScript**: v4.5+ (v5.0+ recommended)
- **Node.js**: v16+ (v18+ recommended)