用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/diegosouzapw/awesome-omni-skill --skill api-integration命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Token-efficient tracking for AI orchestration. CLI-first for status updates (~50 tokens), agent fallback for complex ops (~1KB). Use when: updating task status, querying blockers, creating progress files, validating phases.
AshAi extension guidelines for integrating AI capabilities with Ash Framework. Use when implementing vectorization/embeddings, exposing Ash actions as LLM tools, creating prompt-backed actions, or setting up MCP servers. Covers semantic search, LangChain integration, and structured outputs.
This skill should be used when solving hard questions, complex architectural problems, or debugging issues that benefit from GPT-5 Pro or GPT-5.1 thinking models with large file context. Use when standard Claude analysis needs deeper reasoning or extended context windows.
基于 SOC 职业分类
正在显示 SKILL.md
| name | api-integration |
| description | API 集成和设计最佳实践。用于设计、实现和优化 RESTful API、GraphQL API 或其他 API 集成。包括错误处理、认证、限流、版本控制等。 |
| allowed-tools | Read, Grep, Glob, Edit, Bash |
✅ 好的命名
GET /api/v1/users
GET /api/v1/users/{id}
POST /api/v1/users
PUT /api/v1/users/{id}
DELETE /api/v1/users/{id}
❌ 不好的命名
GET /api/v1/getUsers
POST /api/v1/createUser
2xx - 成功
200 OK - 成功返回数据
201 Created - 资源创建成功
204 No Content - 成功但无返回内容
4xx - 客户端错误
400 Bad Request - 请求参数错误
401 Unauthorized - 未认证
403 Forbidden - 无权限
404 Not Found - 资源不存在
422 Unprocessable Entity - 验证失败
429 Too Many Requests - 限流
5xx - 服务器错误
500 Internal Server Error - 服务器错误
502 Bad Gateway - 网关错误
503 Service Unavailable - 服务不可用
interface ApiResponse<T> {
success: boolean;
data?: T;
error?: {
code: string;
message: string;
details?: any;
};
meta?: {
timestamp: string;
requestId: string;
};
}
{
"success": true,
"data": {
"id": "123",
"name": "John Doe"
},
"meta": {
"timestamp": "2024-01-14T10:00:00Z",
"requestId": "req_abc123"
}
}
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid email format",
"details": {
"field": "email",
"value": "invalid-email"
}
},
"meta": {
"timestamp": "2024-01-14T10:00:00Z",
"requestId": "req_abc123"
}
}
GET /api/v1/users?page=1&limit=20
Response:
{
"data": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 100,
"totalPages": 5
}
}
GET /api/v1/users?cursor=abc123&limit=20
Response:
{
"data": [...],
"pagination": {
"nextCursor": "def456",
"hasMore": true
}
}
// 请求头
Authorization: Bearer <jwt_token>
// Token 结构
{
"sub": "user_id",
"exp": 1234567890,
"iat": 1234567890,
"roles": ["user", "admin"]
}
// 请求头
X-API-Key: <api_key>
// 或查询参数(不推荐)
GET /api/v1/users?api_key=<api_key>
// Authorization Code Flow
1. GET /oauth/authorize?client_id=...&redirect_uri=...
2. POST /oauth/token
{
"grant_type": "authorization_code",
"code": "...",
"client_id": "...",
"client_secret": "..."
}
enum ErrorCode {
VALIDATION_ERROR = 'VALIDATION_ERROR',
AUTHENTICATION_ERROR = 'AUTHENTICATION_ERROR',
AUTHORIZATION_ERROR = 'AUTHORIZATION_ERROR',
NOT_FOUND = 'NOT_FOUND',
CONFLICT = 'CONFLICT',
RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED',
INTERNAL_ERROR = 'INTERNAL_ERROR'
}
app.use((err, req, res, next) => {
const statusCode = err.statusCode || 500;
const errorCode = err.code || 'INTERNAL_ERROR';
res.status(statusCode).json({
success: false,
error: {
code: errorCode,
message: err.message,
details: err.details
},
meta: {
timestamp: new Date().toISOString(),
requestId: req.id
}
});
});
// Token Bucket
const rateLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 分钟
max: 100, // 最多 100 个请求
message: 'Too many requests'
});
// 响应头
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1234567890
// 严格限流(登录)
POST /api/v1/auth/login - 5 requests/15min
// 普通限流(读取)
GET /api/v1/users - 100 requests/15min
// 宽松限流(静态资源)
GET /api/v1/public/* - 1000 requests/15min
/api/v1/users
/api/v2/users
Accept: application/vnd.myapi.v1+json
// 支持多版本
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
// 版本废弃通知
res.setHeader('X-API-Deprecated', 'true');
res.setHeader('X-API-Sunset', '2024-12-31');
import { z } from 'zod';
const createUserSchema = z.object({
name: z.string().min(2).max(50),
email: z.string().email(),
age: z.number().int().min(18).max(120)
});
app.post('/api/v1/users', async (req, res) => {
try {
const data = createUserSchema.parse(req.body);
// 处理请求
} catch (error) {
res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid input',
details: error.errors
}
});
}
});
// 强缓存
Cache-Control: public, max-age=3600
// 协商缓存
ETag: "abc123"
Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT
// 不缓存
Cache-Control: no-store, no-cache, must-revalidate
async function getUser(id: string) {
// 尝试从缓存获取
const cached = await redis.get(`user:${id}`);
if (cached) {
return JSON.parse(cached);
}
// 从数据库获取
const user = await db.users.findById(id);
// 写入缓存
await redis.setex(`user:${id}`, 3600, JSON.stringify(user));
return user;
}
openapi: 3.0.0
info:
title: My API
version: 1.0.0
paths:
/users:
get:
summary: Get all users
parameters:
- name: page
in: query
schema:
type: integer
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/UserList'
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
logger.info({
method: req.method,
path: req.path,
statusCode: res.statusCode,
duration,
requestId: req.id
});
});
next();
});
// 响应时间
X-Response-Time: 123ms
// 追踪 ID
X-Trace-Id: abc123
X-Span-Id: def456
app.use(cors({
origin: ['https://example.com'],
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
app.use(helmet({
contentSecurityPolicy: true,
xssFilter: true,
noSniff: true,
hsts: true
}));
// 防止 SQL 注入
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId]);
// 防止 XSS
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(userInput);
describe('GET /api/v1/users', () => {
it('should return users list', async () => {
const response = await request(app)
.get('/api/v1/users')
.expect(200);
expect(response.body.success).toBe(true);
expect(response.body.data).toBeInstanceOf(Array);
});
it('should handle pagination', async () => {
const response = await request(app)
.get('/api/v1/users?page=1&limit=10')
.expect(200);
expect(response.body.pagination.page).toBe(1);
expect(response.body.pagination.limit).toBe(10);
});
});
设计或审查 API 时检查: