@nestjsvn/swagger-sse
Version:
OpenAPI documentation and interactive Swagger UI for NestJS Server-Sent Events endpoints
439 lines (331 loc) • 12.3 kB
Markdown
# Swagger UI SSE Plugin Usage Guide
This guide covers the interactive Swagger UI plugin that provides real-time Server-Sent Events streaming capabilities within the Swagger documentation interface.
## Table of Contents
1. [Overview](#overview)
2. [Basic Setup](#basic-setup)
3. [Advanced Configuration](#advanced-configuration)
4. [UI Features](#ui-features)
5. [Browser Compatibility](#browser-compatibility)
6. [Troubleshooting](#troubleshooting)
7. [API Reference](#api-reference)
## Overview
The Swagger UI SSE Plugin extends the standard Swagger UI interface to provide:
- **Interactive SSE Connections**: Connect to SSE endpoints directly from the documentation
- **Real-time Event Display**: View streaming events with timestamps and formatted JSON
- **Connection Management**: Connect, disconnect, and monitor connection status
- **Event Filtering**: Search and filter events by type or content
- **Export Functionality**: Export event logs as JSON files
- **Auto-reconnection**: Automatic reconnection on connection failures
## Basic Setup
### 1. Install Dependencies
```bash
npm install @nestjsvn/swagger-sse
```
### 2. Replace SwaggerModule.setup
Replace your existing `SwaggerModule.setup()` call with `setupSsePlugin()`:
```typescript
// Before
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api-docs', app, document);
// After
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { setupSsePlugin } from '@nestjsvn/swagger-sse';
const document = SwaggerModule.createDocument(app, config);
setupSsePlugin(app, document, 'api-docs');
```
### 3. Complete Example
```typescript
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder } from '@nestjs/swagger';
import { setupSsePlugin } from '@nestjsvn/swagger-sse';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Enable CORS for SSE
app.enableCors({
origin: true,
credentials: true
});
const config = new DocumentBuilder()
.setTitle('My API')
.setDescription('API with SSE support')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
setupSsePlugin(app, document, 'api-docs');
await app.listen(3000);
}
bootstrap();
```
## Advanced Configuration
### Custom SSE Configuration
Use `setupSsePluginAdvanced()` for custom configuration:
```typescript
import { setupSsePluginAdvanced } from '@nestjsvn/swagger-sse';
setupSsePluginAdvanced(app, document, 'api-docs', {
customSiteTitle: 'My API with SSE',
sseConfig: {
enableEventFiltering: true, // Enable event search/filter
enableEventSearch: true, // Enable text search in events
maxEventLogSize: 2000, // Maximum events to keep in log
enableExport: true, // Enable JSON export
enableReconnection: true, // Auto-reconnect on failures
reconnectionDelay: 3000 // Delay between reconnection attempts (ms)
}
});
```
### Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enableEventFiltering` | boolean | `true` | Enable event type filtering |
| `enableEventSearch` | boolean | `true` | Enable text search in event data |
| `maxEventLogSize` | number | `1000` | Maximum number of events to keep |
| `enableExport` | boolean | `true` | Enable JSON export functionality |
| `enableReconnection` | boolean | `true` | Auto-reconnect on connection failures |
| `reconnectionDelay` | number | `3000` | Delay between reconnection attempts |
## UI Features
### Connection Controls
Each SSE endpoint in the Swagger UI will display:
- **Connect Button**: Establish SSE connection
- **Disconnect Button**: Close SSE connection
- **Connection Status**: Visual indicator (Connected/Connecting/Disconnected/Error)
- **URL Input**: Editable SSE endpoint URL
### Event Log
The event log displays:
- **Real-time Events**: Events appear as they're received
- **Event Type**: Clearly labeled event types
- **Timestamps**: Local time for each event
- **Formatted JSON**: Pretty-printed event data
- **Auto-scroll**: Automatically scrolls to show latest events
### Event Management
- **Search**: Filter events by content (when enabled)
- **Clear Log**: Remove all events from display
- **Export**: Download events as JSON file
- **Event Counter**: Shows total number of events received
- **Connection Timer**: Shows connection duration
### Example UI Interface
```
┌─────────────────────────────────────────────────────────┐
│ SSE Controls │
│ [Connect] [Disconnect] Status: CONNECTED │
│ URL: http://localhost:3000/events/stream │
├─────────────────────────────────────────────────────────┤
│ Event Log [Search] [Clear] [Export] │
│ │
│ user-created 14:30:25 │
│ { │
│ "userId": "user-1", │
│ "username": "User1", │
│ "email": "user1@example.com" │
│ } │
│ │
│ message-received 14:30:27 │
│ { │
│ "messageId": "msg-1", │
│ "content": "Hello World" │
│ } │
├─────────────────────────────────────────────────────────┤
│ Events: 15 Duration: 00:02:34 │
└─────────────────────────────────────────────────────────┘
```
## Browser Compatibility
### Supported Browsers
- **Chrome**: 6+ (full support)
- **Firefox**: 6+ (full support)
- **Safari**: 5+ (full support)
- **Edge**: 12+ (full support)
- **IE**: 11+ (with polyfill)
### EventSource Polyfill
For older browsers, include an EventSource polyfill:
```html
<script src="https://cdn.jsdelivr.net/npm/eventsource-polyfill@0.9.6/dist/eventsource.min.js"></script>
```
### Mobile Support
The UI is responsive and works on mobile devices with EventSource support:
- **iOS Safari**: 4+
- **Android Chrome**: 4.4+
- **Mobile Firefox**: 45+
## Troubleshooting
### Common Issues
#### 1. SSE Interface Not Appearing
**Problem**: SSE controls don't appear for endpoints.
**Solutions**:
- Ensure endpoints use `@ApiSse()` decorator
- Check that `x-sse-endpoint: true` is in OpenAPI spec
- Verify `setupSsePlugin()` is used instead of `SwaggerModule.setup()`
#### 2. Connection Failures
**Problem**: Cannot connect to SSE endpoints.
**Solutions**:
- Check CORS configuration:
```typescript
app.enableCors({
origin: true,
credentials: true
});
```
- Verify endpoint URL is correct
- Check network connectivity
- Ensure SSE endpoint is running
#### 3. Events Not Displaying
**Problem**: Connected but no events appear.
**Solutions**:
- Check browser console for errors
- Verify SSE endpoint is sending events
- Check event format (should be valid SSE format)
- Ensure event types match those in `@ApiSse()` decorator
#### 4. Auto-reconnection Not Working
**Problem**: Connection doesn't automatically reconnect.
**Solutions**:
- Enable reconnection in configuration:
```typescript
sseConfig: {
enableReconnection: true,
reconnectionDelay: 3000
}
```
- Check browser console for reconnection attempts
- Verify server is accepting new connections
### Debug Mode
Enable debug logging by setting:
```javascript
window.SSE_DEBUG = true;
```
This will log detailed information about:
- Connection attempts
- Event reception
- UI updates
- Error conditions
### Network Issues
For network-related issues:
1. **Check browser Network tab** for failed requests
2. **Verify SSE headers** in response:
```
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
```
3. **Test with curl**:
```bash
curl -N -H "Accept: text/event-stream" http://localhost:3000/events/stream
```
## API Reference
### setupSsePlugin()
Basic setup function for SSE plugin integration.
```typescript
function setupSsePlugin(
app: INestApplication,
document: OpenAPIObject,
path: string,
options?: SwaggerCustomOptions
): void
```
**Parameters**:
- `app`: NestJS application instance
- `document`: OpenAPI document from `SwaggerModule.createDocument()`
- `path`: Swagger UI path (e.g., 'api-docs')
- `options`: Optional Swagger customization options
### setupSsePluginAdvanced()
Advanced setup with custom SSE configuration.
```typescript
function setupSsePluginAdvanced(
app: INestApplication,
document: OpenAPIObject,
path: string,
options?: SwaggerCustomOptions & {
sseConfig?: SsePluginConfig;
}
): void
```
**Additional Parameters**:
- `options.sseConfig`: SSE-specific configuration options
### SsePluginConfig Interface
```typescript
interface SsePluginConfig {
enableEventFiltering?: boolean;
enableEventSearch?: boolean;
maxEventLogSize?: number;
enableExport?: boolean;
enableReconnection?: boolean;
reconnectionDelay?: number;
}
```
### Client-side API
The plugin exposes global functions for programmatic control:
```javascript
// Connect to SSE endpoint
window.ssePlugin.connect(url, eventTypes);
// Disconnect from endpoint
window.ssePlugin.disconnect(url);
// Clear event log
window.ssePlugin.clearLog(url);
// Export events
window.ssePlugin.exportEvents(url);
```
## Best Practices
### 1. Error Handling
Always implement proper error handling in your SSE endpoints:
```typescript
@Sse('stream')
@ApiSse({
events: {
'data': DataDto,
'error': ErrorDto
}
})
streamData(): Observable<MessageEvent> {
return this.dataService.watchData().pipe(
map(data => ({ type: 'data', data })),
catchError(error => of({ type: 'error', data: { message: error.message } }))
);
}
```
### 2. Rate Limiting
Implement rate limiting for SSE endpoints to prevent abuse:
```typescript
import { Throttle } from '@nestjs/throttler';
@Sse('stream')
@Throttle(10, 60) // 10 requests per minute
@ApiSse({ events: { 'data': DataDto } })
streamData(): Observable<MessageEvent> {
// Implementation
}
```
### 3. Authentication
Secure SSE endpoints with proper authentication:
```typescript
import { UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Sse('private-stream')
@UseGuards(AuthGuard('jwt'))
@ApiSse({
security: [{ bearer: [] }],
events: { 'private-data': PrivateDataDto }
})
streamPrivateData(): Observable<MessageEvent> {
// Implementation
}
```
### 4. Resource Management
Properly manage resources in SSE streams:
```typescript
@Sse('stream')
@ApiSse({ events: { 'data': DataDto } })
streamData(): Observable<MessageEvent> {
return this.dataService.watchData().pipe(
takeUntil(this.destroy$), // Cleanup on component destroy
share() // Share subscription among multiple clients
);
}
```
## Examples
See the [examples directory](../examples/) for complete working examples:
- [Basic UI Integration](../examples/ui-integration.ts)
- [Advanced Configuration](../examples/advanced-sse.ts)
- [Authentication Example](../examples/authenticated-sse.ts)
- [Error Handling](../examples/error-handling.ts)
## Support
For issues and questions:
- [GitHub Issues](https://github.com/nestjsx/swagger-sse/issues)
- [Documentation](https://github.com/nestjsx/swagger-sse/docs)
- [Examples](https://github.com/nestjsx/swagger-sse/examples)