backend-development by skillcreatorai/ai-agent-skills
npx skills add https://github.com/skillcreatorai/ai-agent-skills --skill backend-developmentGET /users # 列出用户
POST /users # 创建用户
GET /users/:id # 获取用户
PUT /users/:id # 更新用户(完整)
PATCH /users/:id # 更新用户(部分)
DELETE /users/:id # 删除用户
GET /users/:id/posts # 列出用户的帖子
POST /users/:id/posts # 为用户创建帖子
{
"data": { ... },
"meta": {
"page": 1,
"per_page": 20,
"total": 100
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "无效输入",
"details": [
{ "field": "email", "message": "格式无效" }
]
}
}
-- 使用 UUID 作为公开 ID
CREATE TABLE users (
id SERIAL PRIMARY KEY,
public_id UUID DEFAULT gen_random_uuid() UNIQUE,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 软删除
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMPTZ;
-- 索引
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_created ON users(created_at DESC);
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
-- 使用游标进行分页
SELECT * FROM posts
WHERE created_at < $cursor
ORDER BY created_at DESC
LIMIT 20;
-- 高效计数
SELECT reltuples::bigint AS estimate
FROM pg_class WHERE relname = 'users';
interface TokenPayload {
sub: string; // 用户 ID
iat: number; // 签发时间
exp: number; // 过期时间
scope: string[]; // 权限
}
function verifyToken(token: string): TokenPayload {
return jwt.verify(token, SECRET) as TokenPayload;
}
async function authenticate(req: Request, res: Response, next: Next) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({ error: '未授权' });
}
try {
req.user = verifyToken(token);
next();
} catch {
res.status(401).json({ error: '令牌无效' });
}
}
// 旁路缓存模式
async function getUser(id: string): Promise<User> {
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;
}
// 缓存失效
async function updateUser(id: string, data: Partial<User>) {
await db.users.update(id, data);
await redis.del(`user:${id}`);
}
const limiter = rateLimit({
windowMs: 60 * 1000, // 1 分钟
max: 100, // 每个窗口 100 个请求
keyGenerator: (req) => req.ip,
handler: (req, res) => {
res.status(429).json({ error: '请求过多' });
}
});
/health 和 /ready 端点每周安装量
240
仓库
GitHub 星标数
953
首次出现
2026年1月20日
安全审计
安装于
opencode204
gemini-cli196
codex190
cursor181
github-copilot179
amp152
GET /users # List users
POST /users # Create user
GET /users/:id # Get user
PUT /users/:id # Update user (full)
PATCH /users/:id # Update user (partial)
DELETE /users/:id # Delete user
GET /users/:id/posts # List user's posts
POST /users/:id/posts # Create post for user
{
"data": { ... },
"meta": {
"page": 1,
"per_page": 20,
"total": 100
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input",
"details": [
{ "field": "email", "message": "Invalid format" }
]
}
}
-- Use UUIDs for public IDs
CREATE TABLE users (
id SERIAL PRIMARY KEY,
public_id UUID DEFAULT gen_random_uuid() UNIQUE,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Soft deletes
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMPTZ;
-- Indexes
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_created ON users(created_at DESC);
-- Pagination with cursor
SELECT * FROM posts
WHERE created_at < $cursor
ORDER BY created_at DESC
LIMIT 20;
-- Efficient counting
SELECT reltuples::bigint AS estimate
FROM pg_class WHERE relname = 'users';
interface TokenPayload {
sub: string; // User ID
iat: number; // Issued at
exp: number; // Expiration
scope: string[]; // Permissions
}
function verifyToken(token: string): TokenPayload {
return jwt.verify(token, SECRET) as TokenPayload;
}
async function authenticate(req: Request, res: Response, next: Next) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
try {
req.user = verifyToken(token);
next();
} catch {
res.status(401).json({ error: 'Invalid token' });
}
}
// Cache-aside pattern
async function getUser(id: string): Promise<User> {
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;
}
// Cache invalidation
async function updateUser(id: string, data: Partial<User>) {
await db.users.update(id, data);
await redis.del(`user:${id}`);
}
const limiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 100, // 100 requests per window
keyGenerator: (req) => req.ip,
handler: (req, res) => {
res.status(429).json({ error: 'Too many requests' });
}
});
/health and /ready endpointsWeekly Installs
240
Repository
GitHub Stars
953
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode204
gemini-cli196
codex190
cursor181
github-copilot179
amp152
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
140,500 周安装