Step 1: Update the Config File
Open lib/config.ts
and locate the apiCategories
array in the siteConfig
object.
Example: Adding a new category
// lib/config.ts
export const siteConfig = {
// ... other config
apiCategories: [
// ... existing categories
{
name: "Analytics", // New category name
color: "green", // Choose from: blue, purple, green, yellow, red
endpoints: [
// Define endpoints for this category (see next step)
],
},
],
}
The color
property determines the styling of the category badge. Available options are: blue, purple, green, yellow, and red.
Step 2: Define Endpoints
For each category, define the endpoints that belong to it in the endpoints
array.
Example: Adding endpoints to a category
endpoints: [
{
method: "GET",
path: "/analytics/stats",
description: "Get usage statistics",
mediaType: "application/json",
parameters: [
{
name: "period",
type: "string",
required: false,
description: "Time period (daily, weekly, monthly)"
},
],
versions: ["v1", "v2"], // Available in both versions
},
// Add more endpoints as needed
],
Each endpoint requires the following properties:
method
: HTTP method (GET, POST, PUT, DELETE)path
: The endpoint path (without /api/v1 or /api/v2 prefix)description
: A brief description of what the endpoint doesmediaType
: The content type returned (e.g., application/json, image/png)parameters
: Array of parameters the endpoint acceptsversions
: Array of API versions this endpoint is available in
Step 3: Add Media Types (if needed)
If your new API returns a media type that isn't already defined, add it to the mediaTypes
array in the config.
Example: Adding a new media type
mediaTypes: [
// ... existing media types
{
type: "application/xml",
description: "XML data format for structured information",
badge: "XML",
},
],
Step 1: Create API Route Files
Create route files for each API version in the appropriate directory structure.
File structure example:
app/
├── api/
│ ├── v1/
│ │ └── analytics/
│ │ └── stats/
│ │ └── route.ts
│ └── v2/
│ └── analytics/
│ └── stats/
│ └── route.ts
The file structure should match the endpoint path defined in the config. For example, if your endpoint is /analytics/stats
, create files at app/api/v1/analytics/stats/route.ts
and app/api/v2/analytics/stats/route.ts
.
Step 2: Implement API Logic
Implement the API logic in the route files. Here's a template for a GET endpoint:
Example: GET endpoint implementation
import { NextResponse } from "next/server"
import { siteConfig } from "@/lib/config"
import { memoryCache } from "@/lib/cache"
// Cache TTL in seconds
const CACHE_TTL = 3600 // 1 hour
export async function GET(request: Request) {
// Check if maintenance mode is enabled
if (siteConfig.maintenance.enabled) {
return new NextResponse(
JSON.stringify(
{
status: siteConfig.maintenance.apiResponse.status,
creator: siteConfig.api.creator,
message: siteConfig.maintenance.apiResponse.message,
},
null,
2
),
{
status: 503, // Service Unavailable
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "no-store",
},
}
)
}
// Get query parameters
const { searchParams } = new URL(request.url)
const period = searchParams.get("period") || "daily"
try {
// Create a cache key
const cacheKey = `analytics-stats-${period}`
// Try to get from cache first
const cachedResponse = memoryCache.get(cacheKey)
if (cachedResponse) {
return new NextResponse(
JSON.stringify(
{
status: true,
creator: siteConfig.api.creator,
result: cachedResponse,
cached: true,
version: "v1", // or "v2" depending on the file location
},
null,
2
),
{
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "public, max-age=1800, s-maxage=3600",
},
}
)
}
// Implement your API logic here
const result = {
period,
totalRequests: 12345,
uniqueUsers: 678,
// Add more data as needed
}
// Cache the result
memoryCache.set(cacheKey, result, CACHE_TTL)
// Return the response
return new NextResponse(
JSON.stringify(
{
status: true,
creator: siteConfig.api.creator,
result,
version: "v1", // or "v2" depending on the file location
},
null,
2
),
{
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "public, max-age=1800, s-maxage=3600",
},
}
)
} catch (error) {
return new NextResponse(
JSON.stringify(
{
status: false,
creator: siteConfig.api.creator,
error: error instanceof Error ? error.message : "An error occurred",
version: "v1", // or "v2" depending on the file location
},
null,
2
),
{
status: 500,
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "no-store",
},
}
)
}
}
For POST endpoints, use this template:
Example: POST endpoint implementation
import { NextResponse } from "next/server"
import { siteConfig } from "@/lib/config"
export async function POST(request: Request) {
// Check if maintenance mode is enabled
if (siteConfig.maintenance.enabled) {
return new NextResponse(
JSON.stringify(
{
status: siteConfig.maintenance.apiResponse.status,
creator: siteConfig.api.creator,
message: siteConfig.maintenance.apiResponse.message,
},
null,
2
),
{
status: 503, // Service Unavailable
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "no-store",
},
}
)
}
try {
// Parse request body
let body
try {
body = await request.json()
} catch (error) {
return new NextResponse(
JSON.stringify(
{
status: false,
creator: siteConfig.api.creator,
error: "Invalid JSON in request body",
},
null,
2
),
{
status: 400,
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "no-store",
},
}
)
}
// Validate required parameters
const { param1, param2 } = body
if (!param1 || !param2) {
return new NextResponse(
JSON.stringify(
{
status: false,
creator: siteConfig.api.creator,
error: "Missing required parameters",
},
null,
2
),
{
status: 400,
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "no-store",
},
}
)
}
// Implement your API logic here
const result = {
// Process the request and generate a response
}
// Return the response
return new NextResponse(
JSON.stringify(
{
status: true,
creator: siteConfig.api.creator,
result,
version: "v1", // or "v2" depending on the file location
},
null,
2
),
{
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "no-store", // Don't cache POST responses
},
}
)
} catch (error) {
return new NextResponse(
JSON.stringify(
{
status: false,
creator: siteConfig.api.creator,
error: error instanceof Error ? error.message : "An error occurred",
version: "v1", // or "v2" depending on the file location
},
null,
2
),
{
status: 500,
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "no-store",
},
}
)
}
}
Step 3: Implement Caching (Recommended)
For better performance, implement caching for your API responses using the memoryCache
utility.
Caching best practices:
- Cache GET requests that don't change frequently
- Use appropriate TTL (Time To Live) values based on how often the data changes
- Include cache status in the response (cached: true/false)
- Don't cache sensitive or user-specific data
- Set appropriate Cache-Control headers:
public, max-age=1800, s-maxage=3600
for cacheable responsesno-store
for non-cacheable responses
Step 1: Local Testing
Test your API locally before deploying to production.
Start the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
Once the server is running, you can test your API using the built-in API testing interface at http://localhost:3000
or using tools like Postman, cURL, or the browser.
Step 2: Testing with cURL
Use cURL to test your API endpoints from the command line.
Example: Testing a GET endpoint
curl -X GET "http://localhost:3000/api/v1/analytics/stats?period=weekly"
Example: Testing a POST endpoint
curl -X POST "http://localhost:3000/api/v1/analytics/data" \
-H "Content-Type: application/json" \
-d '{"param1":"value1","param2":"value2"}'
Step 3: Testing Edge Cases
Make sure to test various scenarios to ensure your API is robust.
- Missing required parameters
- Invalid parameter values
- Rate limiting behavior
- Maintenance mode behavior
- Error handling
- Caching behavior
Step 1: Version Control
Commit your changes to the version control system.
Example Git commands:
# Create a new branch
git checkout -b feature/new-analytics-api
# Add your changes
git add .
# Commit your changes
git commit -m "Add analytics API endpoints"
# Push to remote repository
git push origin feature/new-analytics-api
Step 2: Pull Request
Create a pull request to merge your changes into the main branch.
Include a detailed description of your changes in the pull request.
Request a code review from team members before merging.
Step 3: Deployment
Deploy your changes to the production environment.
Deployment process:
- Merge the pull request into the main branch
- The CI/CD pipeline will automatically deploy the changes to the staging environment for final testing
- After successful testing in staging, promote the changes to the production environment
- Monitor the deployment logs and metrics to ensure everything is working as expected
API Design
- Use descriptive and consistent naming for endpoints
- Follow RESTful principles when appropriate
- Use appropriate HTTP methods (GET, POST, PUT, DELETE)
- Return meaningful error messages and status codes
- Validate input parameters thoroughly
- Document all parameters and return values
Performance
- Implement caching for frequently accessed data
- Optimize database queries
- Use pagination for large result sets
- Compress responses when appropriate
- Set appropriate cache headers
Security
- Validate and sanitize all input
- Implement rate limiting to prevent abuse
- Use HTTPS for all API endpoints
- Don't expose sensitive information in responses
- Follow the principle of least privilege
Versioning
- Maintain backward compatibility within a version
- Document breaking changes between versions
- Support multiple versions during transition periods
- Use semantic versioning (major.minor.patch) for API versions
Monitoring and Logging
- Implement comprehensive logging for all API requests
- Monitor API usage, performance, and errors
- Set up alerts for unusual patterns or errors
- Regularly review logs and metrics to identify issues
- Track rate limit usage and adjust limits if necessary