From ca8a7d56f14cfd8ca056ead1eb1e41c270a92417 Mon Sep 17 00:00:00 2001 From: William Tso Date: Wed, 26 Mar 2025 17:39:58 +0800 Subject: [PATCH] swagerr doc --- app/(swagger)/swagger/page.tsx | 143 ++++++++++++++++++++++++++----- docs/swagger-setup.md | 151 +++++++++++++++++++++++++++++++++ 2 files changed, 274 insertions(+), 20 deletions(-) create mode 100644 docs/swagger-setup.md diff --git a/app/(swagger)/swagger/page.tsx b/app/(swagger)/swagger/page.tsx index 5a20c97..4a70351 100644 --- a/app/(swagger)/swagger/page.tsx +++ b/app/(swagger)/swagger/page.tsx @@ -175,7 +175,9 @@ export default function SwaggerPage() { }, '/events/time-series': { get: { + tags: ['events'], summary: 'Get time series data', + description: 'Get time-based analytics data for events', parameters: [ { name: 'startTime', @@ -185,6 +187,7 @@ export default function SwaggerPage() { type: 'string', format: 'date-time', }, + description: 'Start time for time series data (ISO 8601 format)', }, { name: 'endTime', @@ -194,6 +197,7 @@ export default function SwaggerPage() { type: 'string', format: 'date-time', }, + description: 'End time for time series data (ISO 8601 format)', }, ], responses: { @@ -215,12 +219,24 @@ export default function SwaggerPage() { }, }, }, + '400': { + description: 'Bad request', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error', + }, + }, + }, + }, }, }, }, '/events/geo': { get: { + tags: ['events'], summary: 'Get geographic data', + description: 'Get geographic distribution of events', parameters: [ { name: 'startTime', @@ -230,6 +246,7 @@ export default function SwaggerPage() { type: 'string', format: 'date-time', }, + description: 'Start time for geographic data (ISO 8601 format)', }, { name: 'endTime', @@ -239,6 +256,7 @@ export default function SwaggerPage() { type: 'string', format: 'date-time', }, + description: 'End time for geographic data (ISO 8601 format)', }, ], responses: { @@ -260,12 +278,24 @@ export default function SwaggerPage() { }, }, }, + '400': { + description: 'Bad request', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error', + }, + }, + }, + }, }, }, }, '/events/devices': { get: { + tags: ['events'], summary: 'Get device analytics data', + description: 'Get device-related analytics for events', parameters: [ { name: 'startTime', @@ -275,6 +305,7 @@ export default function SwaggerPage() { type: 'string', format: 'date-time', }, + description: 'Start time for device analytics (ISO 8601 format)', }, { name: 'endTime', @@ -284,6 +315,7 @@ export default function SwaggerPage() { type: 'string', format: 'date-time', }, + description: 'End time for device analytics (ISO 8601 format)', }, ], responses: { @@ -302,6 +334,16 @@ export default function SwaggerPage() { }, }, }, + '400': { + description: 'Bad request', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error', + }, + }, + }, + }, }, }, }, @@ -408,22 +450,56 @@ export default function SwaggerPage() { TimeSeriesData: { type: 'object', properties: { - timestamp: { type: 'string', format: 'date-time' }, - events: { type: 'number' }, - visitors: { type: 'number' }, - conversions: { type: 'number' }, + timestamp: { + type: 'string', + format: 'date-time', + description: 'Time point in the series', + }, + events: { + type: 'number', + description: 'Number of events at this time point', + }, + visitors: { + type: 'number', + description: 'Number of unique visitors at this time point', + }, + conversions: { + type: 'number', + description: 'Number of conversions at this time point', + }, }, }, GeoData: { type: 'object', properties: { - location: { type: 'string' }, - country: { type: 'string' }, - region: { type: 'string' }, - city: { type: 'string' }, - visits: { type: 'number' }, - visitors: { type: 'number' }, - percentage: { type: 'number' }, + location: { + type: 'string', + description: 'Location identifier', + }, + country: { + type: 'string', + description: 'Country name', + }, + region: { + type: 'string', + description: 'Region/state name', + }, + city: { + type: 'string', + description: 'City name', + }, + visits: { + type: 'number', + description: 'Number of visits from this location', + }, + visitors: { + type: 'number', + description: 'Number of unique visitors from this location', + }, + percentage: { + type: 'number', + description: 'Percentage of total visits', + }, }, }, DeviceAnalytics: { @@ -434,9 +510,18 @@ export default function SwaggerPage() { items: { type: 'object', properties: { - type: { type: 'string' }, - count: { type: 'number' }, - percentage: { type: 'number' }, + type: { + type: 'string', + description: 'Device type', + }, + count: { + type: 'number', + description: 'Number of visits from this device type', + }, + percentage: { + type: 'number', + description: 'Percentage of total visits', + }, }, }, }, @@ -445,9 +530,18 @@ export default function SwaggerPage() { items: { type: 'object', properties: { - name: { type: 'string' }, - count: { type: 'number' }, - percentage: { type: 'number' }, + name: { + type: 'string', + description: 'Browser name', + }, + count: { + type: 'number', + description: 'Number of visits from this browser', + }, + percentage: { + type: 'number', + description: 'Percentage of total visits', + }, }, }, }, @@ -456,9 +550,18 @@ export default function SwaggerPage() { items: { type: 'object', properties: { - name: { type: 'string' }, - count: { type: 'number' }, - percentage: { type: 'number' }, + name: { + type: 'string', + description: 'Operating system name', + }, + count: { + type: 'number', + description: 'Number of visits from this OS', + }, + percentage: { + type: 'number', + description: 'Percentage of total visits', + }, }, }, }, diff --git a/docs/swagger-setup.md b/docs/swagger-setup.md new file mode 100644 index 0000000..618be53 --- /dev/null +++ b/docs/swagger-setup.md @@ -0,0 +1,151 @@ +# Setting up Swagger UI in Next.js + +This guide explains how to set up Swagger UI in a Next.js application using route groups. + +## Directory Structure + +The recommended directory structure for Swagger documentation: + +``` +app/ + (swagger)/ # Route group for swagger-related pages + swagger/ # Actual swagger route + page.tsx # Swagger UI component +``` + +## Installation + +1. Add Swagger UI dependencies to your project: + +```json +{ + "dependencies": { + "swagger-ui-react": "^5.12.0", + "swagger-ui-dist": "^5.12.0" + }, + "devDependencies": { + "@types/swagger-ui-react": "^4.18.3" + } +} +``` + +2. Install webpack style loaders for handling Swagger UI CSS: + +```bash +pnpm add -D style-loader css-loader +``` + +## Next.js Configuration + +Create or update `next.config.js` to handle Swagger UI CSS: + +```javascript +/** @type {import('next').NextConfig} */ +const nextConfig = { + transpilePackages: ['swagger-ui-react'], + webpack: (config) => { + config.module.rules.push({ + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }); + return config; + }, +}; + +module.exports = nextConfig; +``` + +## Swagger UI Component + +Create `app/(swagger)/swagger/page.tsx`: + +```typescript +"use client"; + +import { useEffect } from 'react'; +import SwaggerUI from 'swagger-ui-react'; +import 'swagger-ui-react/swagger-ui.css'; + +export default function SwaggerPage() { + useEffect(() => { + document.title = 'API Documentation - ShortURL Analytics'; + }, []); + + const swaggerConfig = { + openapi: '3.0.0', + info: { + title: 'Your API Title', + version: '1.0.0', + description: 'API documentation', + contact: { + name: 'API Support', + email: 'support@example.com', + }, + license: { + name: 'MIT', + url: 'https://opensource.org/licenses/MIT', + }, + }, + // ... your API configuration + }; + + return ( +
+
+

API Documentation

+

+ Explore and test the API endpoints using the interactive documentation below. +

+
+ +
+ ); +} +``` + +## Best Practices + +1. **Route Groups**: Use route groups `(groupname)` to organize related pages without affecting the URL structure. + +2. **API Documentation**: + - Add detailed descriptions for all endpoints + - Include parameter descriptions and constraints + - Define response schemas + - Document error responses + - Use appropriate data formats (UUID, URI, etc.) + - Group related endpoints using tags + +3. **Swagger Configuration**: + - Add contact information + - Include license details + - Set appropriate servers configuration + - Define required fields + - Add parameter validations (min/max values) + +## Common Issues + +1. **Route Conflicts**: Avoid parallel routes that resolve to the same path. For example, don't have both `app/swagger/page.tsx` and `app/(group)/swagger/page.tsx` as they would conflict. + +2. **CSS Loading**: Make sure to: + - Import Swagger UI CSS + - Configure webpack in `next.config.js` + - Use the `"use client"` directive as Swagger UI is a client-side component + +3. **React Version Compatibility**: Be aware of potential peer dependency warnings between Swagger UI React and your React version. You might need to use `--legacy-peer-deps` or adjust your React version accordingly. + +## Accessing the Documentation + +After setup, your Swagger documentation will be available at `/swagger` in your application. The UI provides: +- Interactive API documentation +- Request/response examples +- Try-it-out functionality +- Schema definitions +- Error responses + +## Maintenance + +Keep your Swagger documentation up-to-date by: +- Updating the OpenAPI specification when adding or modifying endpoints +- Maintaining accurate parameter descriptions +- Keeping example values relevant +- Updating response schemas when data structures change \ No newline at end of file