swagerr doc
This commit is contained in:
@@ -175,7 +175,9 @@ export default function SwaggerPage() {
|
|||||||
},
|
},
|
||||||
'/events/time-series': {
|
'/events/time-series': {
|
||||||
get: {
|
get: {
|
||||||
|
tags: ['events'],
|
||||||
summary: 'Get time series data',
|
summary: 'Get time series data',
|
||||||
|
description: 'Get time-based analytics data for events',
|
||||||
parameters: [
|
parameters: [
|
||||||
{
|
{
|
||||||
name: 'startTime',
|
name: 'startTime',
|
||||||
@@ -185,6 +187,7 @@ export default function SwaggerPage() {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'date-time',
|
format: 'date-time',
|
||||||
},
|
},
|
||||||
|
description: 'Start time for time series data (ISO 8601 format)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'endTime',
|
name: 'endTime',
|
||||||
@@ -194,6 +197,7 @@ export default function SwaggerPage() {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'date-time',
|
format: 'date-time',
|
||||||
},
|
},
|
||||||
|
description: 'End time for time series data (ISO 8601 format)',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
responses: {
|
responses: {
|
||||||
@@ -215,12 +219,24 @@ export default function SwaggerPage() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'400': {
|
||||||
|
description: 'Bad request',
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: {
|
||||||
|
$ref: '#/components/schemas/Error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'/events/geo': {
|
'/events/geo': {
|
||||||
get: {
|
get: {
|
||||||
|
tags: ['events'],
|
||||||
summary: 'Get geographic data',
|
summary: 'Get geographic data',
|
||||||
|
description: 'Get geographic distribution of events',
|
||||||
parameters: [
|
parameters: [
|
||||||
{
|
{
|
||||||
name: 'startTime',
|
name: 'startTime',
|
||||||
@@ -230,6 +246,7 @@ export default function SwaggerPage() {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'date-time',
|
format: 'date-time',
|
||||||
},
|
},
|
||||||
|
description: 'Start time for geographic data (ISO 8601 format)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'endTime',
|
name: 'endTime',
|
||||||
@@ -239,6 +256,7 @@ export default function SwaggerPage() {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'date-time',
|
format: 'date-time',
|
||||||
},
|
},
|
||||||
|
description: 'End time for geographic data (ISO 8601 format)',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
responses: {
|
responses: {
|
||||||
@@ -260,12 +278,24 @@ export default function SwaggerPage() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'400': {
|
||||||
|
description: 'Bad request',
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: {
|
||||||
|
$ref: '#/components/schemas/Error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'/events/devices': {
|
'/events/devices': {
|
||||||
get: {
|
get: {
|
||||||
|
tags: ['events'],
|
||||||
summary: 'Get device analytics data',
|
summary: 'Get device analytics data',
|
||||||
|
description: 'Get device-related analytics for events',
|
||||||
parameters: [
|
parameters: [
|
||||||
{
|
{
|
||||||
name: 'startTime',
|
name: 'startTime',
|
||||||
@@ -275,6 +305,7 @@ export default function SwaggerPage() {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'date-time',
|
format: 'date-time',
|
||||||
},
|
},
|
||||||
|
description: 'Start time for device analytics (ISO 8601 format)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'endTime',
|
name: 'endTime',
|
||||||
@@ -284,6 +315,7 @@ export default function SwaggerPage() {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'date-time',
|
format: 'date-time',
|
||||||
},
|
},
|
||||||
|
description: 'End time for device analytics (ISO 8601 format)',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
responses: {
|
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: {
|
TimeSeriesData: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
timestamp: { type: 'string', format: 'date-time' },
|
timestamp: {
|
||||||
events: { type: 'number' },
|
type: 'string',
|
||||||
visitors: { type: 'number' },
|
format: 'date-time',
|
||||||
conversions: { type: 'number' },
|
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: {
|
GeoData: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
location: { type: 'string' },
|
location: {
|
||||||
country: { type: 'string' },
|
type: 'string',
|
||||||
region: { type: 'string' },
|
description: 'Location identifier',
|
||||||
city: { type: 'string' },
|
},
|
||||||
visits: { type: 'number' },
|
country: {
|
||||||
visitors: { type: 'number' },
|
type: 'string',
|
||||||
percentage: { type: 'number' },
|
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: {
|
DeviceAnalytics: {
|
||||||
@@ -434,9 +510,18 @@ export default function SwaggerPage() {
|
|||||||
items: {
|
items: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
type: { type: 'string' },
|
type: {
|
||||||
count: { type: 'number' },
|
type: 'string',
|
||||||
percentage: { type: 'number' },
|
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: {
|
items: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
name: { type: 'string' },
|
name: {
|
||||||
count: { type: 'number' },
|
type: 'string',
|
||||||
percentage: { type: 'number' },
|
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: {
|
items: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
name: { type: 'string' },
|
name: {
|
||||||
count: { type: 'number' },
|
type: 'string',
|
||||||
percentage: { type: 'number' },
|
description: 'Operating system name',
|
||||||
|
},
|
||||||
|
count: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Number of visits from this OS',
|
||||||
|
},
|
||||||
|
percentage: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Percentage of total visits',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
151
docs/swagger-setup.md
Normal file
151
docs/swagger-setup.md
Normal file
@@ -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 (
|
||||||
|
<div className="container mx-auto px-4 py-8">
|
||||||
|
<div className="mb-8">
|
||||||
|
<h1 className="text-3xl font-bold mb-2">API Documentation</h1>
|
||||||
|
<p className="text-gray-600">
|
||||||
|
Explore and test the API endpoints using the interactive documentation below.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<SwaggerUI spec={swaggerConfig} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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
|
||||||
Reference in New Issue
Block a user