api-docs-generator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAPI Docs Generator
API文档生成器
Generate comprehensive, developer-friendly API documentation automatically.
自动生成全面且对开发者友好的API文档。
Core Workflow
核心工作流
- Scan routes: Find all API route definitions
- Extract schemas: Request/response types, params
- Generate docs: Markdown/HTML documentation
- Add examples: Request/response examples
- Document errors: Error codes and handling
- Create guides: Authentication, getting started
- 扫描路由:查找所有API路由定义
- 提取模式:请求/响应类型、参数
- 生成文档:Markdown/HTML格式文档
- 添加示例:请求/响应示例
- 记录错误:错误码及处理方式
- 创建指南:认证、快速入门
Documentation Structure
文档结构
docs/
├── api/
│ ├── index.md # API overview
│ ├── authentication.md # Auth guide
│ ├── errors.md # Error reference
│ ├── rate-limiting.md # Rate limit info
│ └── endpoints/
│ ├── users.md
│ ├── products.md
│ └── orders.md
├── guides/
│ ├── getting-started.md
│ ├── pagination.md
│ └── webhooks.md
└── sdks/
├── javascript.md
├── python.md
└── curl.mddocs/
├── api/
│ ├── index.md # API概览
│ ├── authentication.md # 认证指南
│ ├── errors.md # 错误参考
│ ├── rate-limiting.md # 限流信息
│ └── endpoints/
│ ├── users.md
│ ├── products.md
│ └── orders.md
├── guides/
│ ├── getting-started.md
│ ├── pagination.md
│ └── webhooks.md
└── sdks/
├── javascript.md
├── python.md
└── curl.mdGenerator Script
生成器脚本
typescript
// scripts/generate-api-docs.ts
import * as fs from "fs";
import * as path from "path";
interface RouteInfo {
method: string;
path: string;
name: string;
description?: string;
params?: ParamInfo[];
queryParams?: ParamInfo[];
requestBody?: SchemaInfo;
responses?: ResponseInfo[];
auth?: boolean;
tags?: string[];
}
interface ParamInfo {
name: string;
type: string;
required: boolean;
description?: string;
example?: string;
}
interface SchemaInfo {
type: string;
properties?: Record<string, PropertyInfo>;
required?: string[];
example?: object;
}
interface PropertyInfo {
type: string;
description?: string;
example?: unknown;
enum?: string[];
format?: string;
}
interface ResponseInfo {
status: number;
description: string;
schema?: SchemaInfo;
example?: object;
}
interface DocsOptions {
title: string;
baseUrl: string;
version: string;
outputDir: string;
format: "markdown" | "html" | "docusaurus";
}
function generateApiDocs(routes: RouteInfo[], options: DocsOptions): void {
const { outputDir } = options;
// Create directories
fs.mkdirSync(path.join(outputDir, "api", "endpoints"), { recursive: true });
fs.mkdirSync(path.join(outputDir, "guides"), { recursive: true });
// Generate overview
generateOverview(options);
// Generate auth docs
generateAuthDocs(options);
// Generate error docs
generateErrorDocs(options);
// Group routes by resource
const groupedRoutes = groupRoutesByResource(routes);
// Generate endpoint docs
for (const [resource, resourceRoutes] of Object.entries(groupedRoutes)) {
const content = generateEndpointDoc(resource, resourceRoutes, options);
const filePath = path.join(outputDir, "api", "endpoints", `${resource}.md`);
fs.writeFileSync(filePath, content);
}
// Generate getting started guide
generateGettingStarted(routes, options);
}
function generateEndpointDoc(
resource: string,
routes: RouteInfo[],
options: DocsOptions
): string {
const lines: string[] = [];
// Header
lines.push(`# ${capitalize(resource)}`);
lines.push("");
lines.push(`Endpoints for managing ${resource}.`);
lines.push("");
// Table of contents
lines.push("## Endpoints");
lines.push("");
lines.push("| Method | Endpoint | Description |");
lines.push("|--------|----------|-------------|");
for (const route of routes) {
lines.push(
`| \`${route.method}\` | \`${route.path}\` | ${route.description || route.name} |`
);
}
lines.push("");
// Detailed documentation for each endpoint
for (const route of routes) {
lines.push(generateEndpointSection(route, options));
lines.push("");
}
return lines.join("\n");
}
function generateEndpointSection(
route: RouteInfo,
options: DocsOptions
): string {
const lines: string[] = [];
const anchor = route.name.toLowerCase().replace(/\s+/g, "-");
// Endpoint header
lines.push(`## ${route.name} {#${anchor}}`);
lines.push("");
lines.push(
`<span class="method method-${route.method.toLowerCase()}">${route.method}</span> \`${route.path}\``
);
lines.push("");
if (route.description) {
lines.push(route.description);
lines.push("");
}
// Authentication
if (route.auth) {
lines.push("### Authentication");
lines.push("");
lines.push("This endpoint requires authentication. Include the Bearer token in the Authorization header.");
lines.push("");
}
// Path parameters
if (route.params?.length) {
lines.push("### Path Parameters");
lines.push("");
lines.push("| Parameter | Type | Required | Description |");
lines.push("|-----------|------|----------|-------------|");
for (const param of route.params) {
lines.push(
`| \`${param.name}\` | ${param.type} | ${param.required ? "Yes" : "No"} | ${param.description || "-"} |`
);
}
lines.push("");
}
// Query parameters
if (route.queryParams?.length) {
lines.push("### Query Parameters");
lines.push("");
lines.push("| Parameter | Type | Required | Default | Description |");
lines.push("|-----------|------|----------|---------|-------------|");
for (const param of route.queryParams) {
lines.push(
`| \`${param.name}\` | ${param.type} | ${param.required ? "Yes" : "No"} | ${param.example || "-"} | ${param.description || "-"} |`
);
}
lines.push("");
}
// Request body
if (route.requestBody) {
lines.push("### Request Body");
lines.push("");
lines.push("```json");
lines.push(JSON.stringify(route.requestBody.example || {}, null, 2));
lines.push("```");
lines.push("");
if (route.requestBody.properties) {
lines.push("| Field | Type | Required | Description |");
lines.push("|-------|------|----------|-------------|");
for (const [name, prop] of Object.entries(route.requestBody.properties)) {
const required = route.requestBody.required?.includes(name)
? "Yes"
: "No";
lines.push(
`| \`${name}\` | ${prop.type} | ${required} | ${prop.description || "-"} |`
);
}
lines.push("");
}
}
// Responses
lines.push("### Responses");
lines.push("");
const responses = route.responses || [
{ status: 200, description: "Successful response" },
{ status: 400, description: "Bad request" },
{ status: 401, description: "Unauthorized" },
{ status: 404, description: "Not found" },
];
for (const response of responses) {
lines.push(`#### ${response.status} ${response.description}`);
lines.push("");
if (response.example) {
lines.push("```json");
lines.push(JSON.stringify(response.example, null, 2));
lines.push("```");
lines.push("");
}
}
// Example request
lines.push("### Example Request");
lines.push("");
lines.push("```bash");
lines.push(generateCurlExample(route, options));
lines.push("```");
lines.push("");
return lines.join("\n");
}
function generateCurlExample(route: RouteInfo, options: DocsOptions): string {
const parts: string[] = ["curl"];
parts.push(`-X ${route.method}`);
let url = `${options.baseUrl}${route.path}`;
url = url.replace(/:(\w+)/g, "{$1}");
parts.push(`"${url}"`);
if (["POST", "PUT", "PATCH"].includes(route.method)) {
parts.push('-H "Content-Type: application/json"');
}
if (route.auth) {
parts.push('-H "Authorization: Bearer YOUR_TOKEN"');
}
if (route.requestBody?.example) {
parts.push(`-d '${JSON.stringify(route.requestBody.example)}'`);
}
return parts.join(" \\\n ");
}
function generateOverview(options: DocsOptions): void {
const content = `# ${options.title} API Reference
Version: ${options.version}
Base URL: \`${options.baseUrl}\`typescript
// scripts/generate-api-docs.ts
import * as fs from "fs";
import * as path from "path";
interface RouteInfo {
method: string;
path: string;
name: string;
description?: string;
params?: ParamInfo[];
queryParams?: ParamInfo[];
requestBody?: SchemaInfo;
responses?: ResponseInfo[];
auth?: boolean;
tags?: string[];
}
interface ParamInfo {
name: string;
type: string;
required: boolean;
description?: string;
example?: string;
}
interface SchemaInfo {
type: string;
properties?: Record<string, PropertyInfo>;
required?: string[];
example?: object;
}
interface PropertyInfo {
type: string;
description?: string;
example?: unknown;
enum?: string[];
format?: string;
}
interface ResponseInfo {
status: number;
description: string;
schema?: SchemaInfo;
example?: object;
}
interface DocsOptions {
title: string;
baseUrl: string;
version: string;
outputDir: string;
format: "markdown" | "html" | "docusaurus";
}
function generateApiDocs(routes: RouteInfo[], options: DocsOptions): void {
const { outputDir } = options;
// 创建目录
fs.mkdirSync(path.join(outputDir, "api", "endpoints"), { recursive: true });
fs.mkdirSync(path.join(outputDir, "guides"), { recursive: true });
// 生成概览文档
generateOverview(options);
// 生成认证文档
generateAuthDocs(options);
// 生成错误文档
generateErrorDocs(options);
// 按资源分组路由
const groupedRoutes = groupRoutesByResource(routes);
// 生成端点文档
for (const [resource, resourceRoutes] of Object.entries(groupedRoutes)) {
const content = generateEndpointDoc(resource, resourceRoutes, options);
const filePath = path.join(outputDir, "api", "endpoints", `${resource}.md`);
fs.writeFileSync(filePath, content);
}
// 生成快速入门指南
generateGettingStarted(routes, options);
}
function generateEndpointDoc(
resource: string,
routes: RouteInfo[],
options: DocsOptions
): string {
const lines: string[] = [];
// 标题
lines.push(`# ${capitalize(resource)}`);
lines.push("");
lines.push(`用于管理${resource}的端点。`);
lines.push("");
// 目录
lines.push("## 端点列表");
lines.push("");
lines.push("| 请求方法 | 端点路径 | 描述 |");
lines.push("|--------|----------|-------------|");
for (const route of routes) {
lines.push(
`| \`${route.method}\` | \`${route.path}\` | ${route.description || route.name} |`
);
}
lines.push("");
// 每个端点的详细文档
for (const route of routes) {
lines.push(generateEndpointSection(route, options));
lines.push("");
}
return lines.join("\n");
}
function generateEndpointSection(
route: RouteInfo,
options: DocsOptions
): string {
const lines: string[] = [];
const anchor = route.name.toLowerCase().replace(/\s+/g, "-");
// 端点标题
lines.push(`## ${route.name} {#${anchor}}`);
lines.push("");
lines.push(
`<span class="method method-${route.method.toLowerCase()}">${route.method}</span> \`${route.path}\``
);
lines.push("");
if (route.description) {
lines.push(route.description);
lines.push("");
}
// 认证说明
if (route.auth) {
lines.push("### 认证要求");
lines.push("");
lines.push("该端点需要认证,请在Authorization请求头中携带Bearer令牌。");
lines.push("");
}
// 路径参数
if (route.params?.length) {
lines.push("### 路径参数");
lines.push("");
lines.push("| 参数名 | 类型 | 是否必填 | 描述 |");
lines.push("|-----------|------|----------|-------------|");
for (const param of route.params) {
lines.push(
`| \`${param.name}\` | ${param.type} | ${param.required ? "是" : "否"} | ${param.description || "-"} |`
);
}
lines.push("");
}
// 查询参数
if (route.queryParams?.length) {
lines.push("### 查询参数");
lines.push("");
lines.push("| 参数名 | 类型 | 是否必填 | 默认值 | 描述 |");
lines.push("|-----------|------|----------|---------|-------------|");
for (const param of route.queryParams) {
lines.push(
`| \`${param.name}\` | ${param.type} | ${param.required ? "是" : "否"} | ${param.example || "-"} | ${param.description || "-"} |`
);
}
lines.push("");
}
// 请求体
if (route.requestBody) {
lines.push("### 请求体");
lines.push("");
lines.push("```json");
lines.push(JSON.stringify(route.requestBody.example || {}, null, 2));
lines.push("```");
lines.push("");
if (route.requestBody.properties) {
lines.push("| 字段名 | 类型 | 是否必填 | 描述 |");
lines.push("|-------|------|----------|-------------|");
for (const [name, prop] of Object.entries(route.requestBody.properties)) {
const required = route.requestBody.required?.includes(name)
? "是"
: "否";
lines.push(
`| \`${name}\` | ${prop.type} | ${required} | ${prop.description || "-"} |`
);
}
lines.push("");
}
}
// 响应示例
lines.push("### 响应结果");
lines.push("");
const responses = route.responses || [
{ status: 200, description: "请求成功" },
{ status: 400, description: "请求参数错误" },
{ status: 401, description: "未授权访问" },
{ status: 404, description: "资源不存在" },
];
for (const response of responses) {
lines.push(`#### ${response.status} ${response.description}`);
lines.push("");
if (response.example) {
lines.push("```json");
lines.push(JSON.stringify(response.example, null, 2));
lines.push("```");
lines.push("");
}
}
// 请求示例
lines.push("### 请求示例");
lines.push("");
lines.push("```bash");
lines.push(generateCurlExample(route, options));
lines.push("```");
lines.push("");
return lines.join("\n");
}
function generateCurlExample(route: RouteInfo, options: DocsOptions): string {
const parts: string[] = ["curl"];
parts.push(`-X ${route.method}`);
let url = `${options.baseUrl}${route.path}`;
url = url.replace(/:(\w+)/g, "{$1}");
parts.push(`"${url}"`);
if (["POST", "PUT", "PATCH"].includes(route.method)) {
parts.push('-H "Content-Type: application/json"');
}
if (route.auth) {
parts.push('-H "Authorization: Bearer YOUR_TOKEN"');
}
if (route.requestBody?.example) {
parts.push(`-d '${JSON.stringify(route.requestBody.example)}'`);
}
return parts.join(" \\\n ");
}
function generateOverview(options: DocsOptions): void {
const content = `# ${options.title} API参考手册
版本:${options.version}
基础URL:\`${options.baseUrl}\`Overview
概览
Welcome to the ${options.title} API documentation. This API provides programmatic access to [describe your service].
欢迎使用${options.title} API文档。本API提供对[请描述你的服务]的程序化访问能力。
Quick Links
快速链接
- Authentication
- Error Handling
- Rate Limiting
- 认证指南
- 错误处理
- 限流说明
Endpoints
端点资源
| Resource | Description |
|---|---|
| Users | User management |
| Products | Product catalog |
| Orders | Order processing |
| 资源 | 描述 |
|---|---|
| 用户 | 用户管理相关端点 |
| 商品 | 商品目录相关端点 |
| 订单 | 订单处理相关端点 |
SDKs & Libraries
SDK与工具库
- JavaScript/TypeScript
- Python
- cURL Examples
- JavaScript/TypeScript
- Python
- cURL示例
Support
支持与帮助
If you have questions or need help, please:
-
Check the FAQ
-
Open an issue on GitHub
-
Contact support@example.com `;fs.writeFileSync(path.join(options.outputDir, "api", "index.md"), content); }
function generateAuthDocs(options: DocsOptions): void {
const content = `# Authentication
The ${options.title} API uses Bearer token authentication.
如果有问题或需要帮助,请:
-
查看常见问题
-
在GitHub上提交Issue
-
联系support@example.com `;fs.writeFileSync(path.join(options.outputDir, "api", "index.md"), content); }
function generateAuthDocs(options: DocsOptions): void {
const content = `# 认证指南
${options.title} API采用Bearer令牌认证机制。
Getting an Access Token
获取访问令牌
Login
登录获取
```bash
curl -X POST "${options.baseUrl}/auth/login" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "your-password"}'
```
Response:
```json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 3600,
"tokenType": "Bearer"
}
```
```bash
curl -X POST "${options.baseUrl}/auth/login" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "your-password"}'
```
响应结果:
```json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 3600,
"tokenType": "Bearer"
}
```
Using the Token
使用令牌
Include the token in the Authorization header of all authenticated requests:
```bash
curl -X GET "${options.baseUrl}/users" \
-H "Authorization: Bearer YOUR_TOKEN"
```
在所有需要认证的请求头中包含Authorization令牌:
```bash
curl -X GET "${options.baseUrl}/users" \
-H "Authorization: Bearer YOUR_TOKEN"
```
Token Expiration
令牌过期
Tokens expire after 1 hour. When a token expires, you'll receive a 401 response:
```json
{
"error": {
"code": "TOKEN_EXPIRED",
"message": "Your access token has expired"
}
}
```
Refresh your token using the refresh endpoint:
```bash
curl -X POST "${options.baseUrl}/auth/refresh" \
-H "Content-Type: application/json" \
-d '{"refreshToken": "YOUR_REFRESH_TOKEN"}'
```
令牌有效期为1小时。令牌过期时,你会收到401状态码响应:
```json
{
"error": {
"code": "TOKEN_EXPIRED",
"message": "你的访问令牌已过期"
}
}
```
通过刷新令牌端点获取新令牌:
```bash
curl -X POST "${options.baseUrl}/auth/refresh" \
-H "Content-Type: application/json" \
-d '{"refreshToken": "YOUR_REFRESH_TOKEN"}'
```
API Keys
API密钥
For server-to-server communication, you can use API keys:
```bash
curl -X GET "${options.baseUrl}/users" \
-H "X-API-Key: YOUR_API_KEY"
```
Generate API keys in your dashboard under Settings > API Keys.
`;
fs.writeFileSync(
path.join(options.outputDir, "api", "authentication.md"),
content
);
}
function generateErrorDocs(options: DocsOptions): void {
const content = `# Error Handling
The API uses conventional HTTP status codes and returns errors in a consistent format.
对于服务器到服务器的通信,你可以使用API密钥:
```bash
curl -X GET "${options.baseUrl}/users" \
-H "X-API-Key: YOUR_API_KEY"
```
在你的控制台中,进入设置>API密钥页面生成API密钥。
`;
fs.writeFileSync(
path.join(options.outputDir, "api", "authentication.md"),
content
);
}
function generateErrorDocs(options: DocsOptions): void {
const content = `# 错误处理
API采用标准HTTP状态码,并返回格式统一的错误信息。
Error Response Format
错误响应格式
```json
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
"field": ["Specific error for this field"]
},
"trace_id": "abc123"
}
}
```
```json
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "易读的错误提示信息",
"details": {
"field": ["该字段的具体错误信息"]
},
"trace_id": "abc123"
}
}
```
HTTP Status Codes
HTTP状态码说明
| Code | Description |
|---|---|
| 200 | OK - Request succeeded |
| 201 | Created - Resource created successfully |
| 204 | No Content - Request succeeded, no content returned |
| 400 | Bad Request - Invalid request data |
| 401 | Unauthorized - Missing or invalid authentication |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Resource doesn't exist |
| 409 | Conflict - Resource already exists |
| 422 | Unprocessable Entity - Validation error |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error - Server error |
| 状态码 | 描述 |
|---|---|
| 200 | 成功 - 请求已处理完成 |
| 201 | 创建成功 - 资源已成功创建 |
| 204 | 无内容 - 请求成功,但无返回数据 |
| 400 | 请求错误 - 请求数据无效 |
| 401 | 未授权 - 缺少或无效的认证信息 |
| 403 | 禁止访问 - 权限不足 |
| 404 | 未找到 - 资源不存在 |
| 409 | 冲突 - 资源已存在 |
| 422 | 处理失败 - 数据验证错误 |
| 429 | 请求频繁 - 超出限流限制 |
| 500 | 服务器错误 - 服务器内部故障 |
Error Codes
错误码说明
Validation Errors
验证错误
| Code | Description |
|---|---|
| `VALIDATION_ERROR` | Request body validation failed |
| `INVALID_FORMAT` | Field format is invalid |
| `REQUIRED_FIELD` | Required field is missing |
| 错误码 | 描述 |
|---|---|
| `VALIDATION_ERROR` | 请求体验证失败 |
| `INVALID_FORMAT` | 字段格式无效 |
| `REQUIRED_FIELD` | 必填字段缺失 |
Authentication Errors
认证错误
| Code | Description |
|---|---|
| `UNAUTHORIZED` | No authentication provided |
| `INVALID_TOKEN` | Token is invalid or malformed |
| `TOKEN_EXPIRED` | Token has expired |
| `INSUFFICIENT_PERMISSIONS` | User lacks required permissions |
| 错误码 | 描述 |
|---|---|
| `UNAUTHORIZED` | 未提供认证信息 |
| `INVALID_TOKEN` | 令牌无效或格式错误 |
| `TOKEN_EXPIRED` | 令牌已过期 |
| `INSUFFICIENT_PERMISSIONS` | 用户权限不足 |
Resource Errors
资源相关错误
| Code | Description |
|---|---|
| `NOT_FOUND` | Resource doesn't exist |
| `ALREADY_EXISTS` | Resource already exists |
| `CONFLICT` | Operation conflicts with current state |
| 错误码 | 描述 |
|---|---|
| `NOT_FOUND` | 资源不存在 |
| `ALREADY_EXISTS` | 资源已存在 |
| `CONFLICT` | 操作与当前资源状态冲突 |
Rate Limiting
限流错误
| Code | Description |
|---|---|
| `RATE_LIMIT_EXCEEDED` | Too many requests |
When rate limited, check the response headers:
```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640000000
```
| 错误码 | 描述 |
|---|---|
| `RATE_LIMIT_EXCEEDED` | 请求次数过多 |
当触发限流时,可查看响应头获取详细信息:
```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640000000
```
Handling Errors
错误处理示例
```typescript
try {
const response = await api.get('/users');
} catch (error) {
if (error.response) {
switch (error.response.status) {
case 401:
// Redirect to login
break;
case 403:
// Show permission denied
break;
case 404:
// Show not found
break;
case 429:
// Implement retry with backoff
break;
default:
// Show generic error
}
}
}
```
`;
fs.writeFileSync(path.join(options.outputDir, "api", "errors.md"), content);
}
function generateGettingStarted(
routes: RouteInfo[],
options: DocsOptions
): void {
const content = `# Getting Started
This guide will help you make your first API request.
```typescript
try {
const response = await api.get('/users');
} catch (error) {
if (error.response) {
switch (error.response.status) {
case 401:
// 跳转到登录页面
break;
case 403:
// 显示权限不足提示
break;
case 404:
// 显示资源不存在提示
break;
case 429:
// 实现退避重试机制
break;
default:
// 显示通用错误提示
}
}
}
```
`;
fs.writeFileSync(path.join(options.outputDir, "api", "errors.md"), content);
}
function generateGettingStarted(
routes: RouteInfo[],
options: DocsOptions
): void {
const content = `# 快速入门
本指南将帮助你完成首次API请求。
Prerequisites
前置条件
- An API key or user account
- A tool to make HTTP requests (curl, Postman, or your preferred HTTP client)
- API密钥或用户账号
- HTTP请求工具(如curl、Postman或你偏好的HTTP客户端)
Step 1: Get Your API Credentials
步骤1:获取API凭证
- Sign up for an account at example.com
- Navigate to Settings > API Keys
- Generate a new API key
- 在example.com注册账号
- 进入设置>API密钥页面
- 生成新的API密钥
Step 2: Make Your First Request
步骤2:发起首次请求
Let's fetch a list of users:
```bash
curl -X GET "${options.baseUrl}/users" \
-H "Authorization: Bearer YOUR_TOKEN"
```
You should receive a response like:
```json
{
"success": true,
"data": [
{
"id": "user_123",
"name": "John Doe",
"email": "john@example.com"
}
],
"meta": {
"page": 1,
"limit": 10,
"total": 1
}
}
```
我们来获取用户列表:
```bash
curl -X GET "${options.baseUrl}/users" \
-H "Authorization: Bearer YOUR_TOKEN"
```
你会收到如下响应:
```json
{
"success": true,
"data": [
{
"id": "user_123",
"name": "John Doe",
"email": "john@example.com"
}
],
"meta": {
"page": 1,
"limit": 10,
"total": 1
}
}
```
Step 3: Create a Resource
步骤3:创建资源
```bash
curl -X POST "${options.baseUrl}/users" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"name": "Jane Doe",
"email": "jane@example.com"
}'
```
```bash
curl -X POST "${options.baseUrl}/users" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"name": "Jane Doe",
"email": "jane@example.com"
}'
```
Next Steps
下一步
-
Read the Authentication Guide
-
Explore the API Reference
-
Check out Error Handling
-
Try the Postman Collection `;fs.writeFileSync( path.join(options.outputDir, "guides", "getting-started.md"), content ); }
function groupRoutesByResource(
routes: RouteInfo[]
): Record<string, RouteInfo[]> {
const groups: Record<string, RouteInfo[]> = {};
for (const route of routes) {
const parts = route.path.split("/").filter(Boolean);
const resource = parts[0] || "api";
if (!groups[resource]) {
groups[resource] = [];
}
groups[resource].push(route);}
return groups;
}
function capitalize(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}
undefined-
阅读认证指南
-
浏览API参考手册
-
查看错误处理
-
尝试Postman集合 `;fs.writeFileSync( path.join(options.outputDir, "guides", "getting-started.md"), content ); }
function groupRoutesByResource(
routes: RouteInfo[]
): Record<string, RouteInfo[]> {
const groups: Record<string, RouteInfo[]> = {};
for (const route of routes) {
const parts = route.path.split("/").filter(Boolean);
const resource = parts[0] || "api";
if (!groups[resource]) {
groups[resource] = [];
}
groups[resource].push(route);}
return groups;
}
function capitalize(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}
undefinedExample Generated Documentation
生成的文档示例
users.md
users.md
markdown
undefinedmarkdown
undefinedUsers
用户
Endpoints for managing users.
用于管理用户的端点。
Endpoints
端点列表
| Method | Endpoint | Description |
|---|---|---|
| | List all users |
| | Get user by ID |
| | Create new user |
| | Update user |
| | Delete user |
| 请求方法 | 端点路径 | 描述 |
|---|---|---|
| | 获取所有用户列表 |
| | 根据ID获取用户详情 |
| | 创建新用户 |
| | 更新用户信息 |
| | 删除用户 |
List Users {#list-users}
获取用户列表 {#list-users}
<span class="method method-get">GET</span>
/api/usersRetrieve a paginated list of users.
<span class="method method-get">GET</span>
/api/users获取分页的用户列表。
Authentication
认证要求
This endpoint requires authentication. Include the Bearer token in the Authorization header.
该端点需要认证,请在Authorization请求头中携带Bearer令牌。
Query Parameters
查询参数
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| integer | No | 1 | Page number |
| integer | No | 10 | Items per page (max 100) |
| string | No | - | Sort field |
| string | No | desc | Sort order (asc/desc) |
| 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
| integer | 否 | 1 | 页码 |
| integer | 否 | 10 | 每页数量(最大100) |
| string | 否 | - | 排序字段 |
| string | 否 | desc | 排序顺序(升序/降序) |
Responses
响应结果
200 OK
200 请求成功
json
{
"success": true,
"data": [
{
"id": "user_abc123",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"createdAt": "2024-01-15T10:30:00Z"
}
],
"meta": {
"page": 1,
"limit": 10,
"total": 156,
"total_pages": 16
}
}json
{
"success": true,
"data": [
{
"id": "user_abc123",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"createdAt": "2024-01-15T10:30:00Z"
}
],
"meta": {
"page": 1,
"limit": 10,
"total": 156,
"total_pages": 16
}
}401 Unauthorized
401 未授权
json
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required"
}
}json
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "需要认证信息"
}
}Example Request
请求示例
bash
curl -X GET "https://api.example.com/users?page=1&limit=10" \
-H "Authorization: Bearer YOUR_TOKEN"bash
curl -X GET "https://api.example.com/users?page=1&limit=10" \
-H "Authorization: Bearer YOUR_TOKEN"Create User {#create-user}
创建用户 {#create-user}
<span class="method method-post">POST</span>
/api/usersCreate a new user account.
<span class="method method-post">POST</span>
/api/users创建新用户账号。
Authentication
认证要求
This endpoint requires authentication. Include the Bearer token in the Authorization header.
该端点需要认证,请在Authorization请求头中携带Bearer令牌。
Request Body
请求体
json
{
"name": "John Doe",
"email": "john@example.com",
"role": "user"
}| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | User's full name |
| string | Yes | User's email (must be unique) |
| string | No | User role (user, admin) |
json
{
"name": "John Doe",
"email": "john@example.com",
"role": "user"
}| 字段名 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
| string | 是 | 用户全名 |
| string | 是 | 用户邮箱(需唯一) |
| string | 否 | 用户角色(user, admin) |
Responses
响应结果
201 Created
201 创建成功
json
{
"success": true,
"data": {
"id": "user_xyz789",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"createdAt": "2024-01-15T10:30:00Z"
}
}json
{
"success": true,
"data": {
"id": "user_xyz789",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"createdAt": "2024-01-15T10:30:00Z"
}
}400 Bad Request
400 请求错误
json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request data",
"details": {
"email": ["Invalid email format"]
}
}
}json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "请求数据无效",
"details": {
"email": ["邮箱格式无效"]
}
}
}Example Request
请求示例
bash
curl -X POST "https://api.example.com/users" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"name": "John Doe", "email": "john@example.com"}'undefinedbash
curl -X POST "https://api.example.com/users" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"name": "John Doe", "email": "john@example.com"}'undefinedCLI Script
CLI脚本
typescript
#!/usr/bin/env node
// scripts/docs-gen.ts
import * as fs from "fs";
import { program } from "commander";
program
.name("docs-gen")
.description("Generate API documentation from routes")
.option("-f, --framework <type>", "Framework (express|nextjs|fastify)", "express")
.option("-s, --source <path>", "Source directory", "./src")
.option("-o, --output <path>", "Output directory", "./docs")
.option("-t, --title <name>", "API title", "My API")
.option("-v, --version <version>", "API version", "1.0.0")
.option("-b, --base-url <url>", "Base URL", "https://api.example.com")
.option("--format <type>", "Output format (markdown|html|docusaurus)", "markdown")
.parse();
const options = program.opts();
async function main() {
const routes = await scanRoutes(options.framework, options.source);
generateApiDocs(routes, {
title: options.title,
baseUrl: options.baseUrl,
version: options.version,
outputDir: options.output,
format: options.format,
});
console.log(`Generated documentation in ${options.output}`);
}
main();typescript
#!/usr/bin/env node
// scripts/docs-gen.ts
import * as fs from "fs";
import { program } from "commander";
program
.name("docs-gen")
.description("从路由生成API文档")
.option("-f, --framework <type>", "框架类型(express|nextjs|fastify)", "express")
.option("-s, --source <path>", "源码目录", "./src")
.option("-o, --output <path>", "输出目录", "./docs")
.option("-t, --title <name>", "API标题", "My API")
.option("-v, --version <version>", "API版本", "1.0.0")
.option("-b, --base-url <url>", "基础URL", "https://api.example.com")
.option("--format <type>", "输出格式(markdown|html|docusaurus)", "markdown")
.parse();
const options = program.opts();
async function main() {
const routes = await scanRoutes(options.framework, options.source);
generateApiDocs(routes, {
title: options.title,
baseUrl: options.baseUrl,
version: options.version,
outputDir: options.output,
format: options.format,
});
console.log(`文档已生成至${options.output}目录`);
}
main();Best Practices
最佳实践
- Keep docs updated: Regenerate docs on route changes
- Include examples: Show real request/response examples
- Document errors: List all possible error codes
- Add authentication guide: Explain how to authenticate
- Use consistent format: Follow same structure for all endpoints
- Version your docs: Match doc versions to API versions
- Make it searchable: Include table of contents and anchors
- Provide SDKs: Link to client libraries and code examples
- 保持文档更新:路由变更时重新生成文档
- 添加示例:展示真实的请求/响应示例
- 记录错误:列出所有可能的错误码
- 完善认证指南:详细说明认证流程
- 格式统一:所有端点遵循相同的文档结构
- 版本化文档:文档版本与API版本保持一致
- 支持搜索:包含目录和锚点
- 提供SDK:链接到客户端库和代码示例
Output Checklist
输出检查清单
- API overview with quick links
- Authentication guide
- Error handling reference
- Endpoint documentation per resource
- Path and query parameters documented
- Request body schemas with field descriptions
- Response examples for all status codes
- cURL examples for each endpoint
- Getting started guide
- SDK/library examples
- 包含快速链接的API概览文档
- 认证指南文档
- 错误处理参考文档
- 按资源分类的端点文档
- 路径和查询参数说明
- 带字段描述的请求体模式
- 所有状态码的响应示例
- 每个端点的cURL请求示例
- 快速入门指南
- SDK/工具库示例文档