UNPKG

@nestjsvn/swagger-sse

Version:

OpenAPI documentation and interactive Swagger UI for NestJS Server-Sent Events endpoints

439 lines (331 loc) 12.3 kB
# 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)