Builds production-ready REST API endpoints with validation, error handling, authentication, and documentation. Follows best practices for security and scalability.
npx skills add https://github.com/lingxling/awesome-skills-cn --skill api-endpoint-builder
Build complete, production-ready REST API endpoints with proper validation, error handling, authentication, and documentation.
For each endpoint, you create:
// Express example
router.post('/api/users', authenticate, validateUser, createUser);
// Fastify example
fastify.post('/api/users', {
preHandler: [authenticate],
schema: userSchema
}, createUser);
Always validate before processing:
const validateUser = (req, res, next) => {
const { email, name, password } = req.body;
if (!email || !email.includes('@')) {
return res.status(400).json({ error: 'Valid email required' });
}
if (!name || name.length < 2) {
return res.status(400).json({ error: 'Name must be at least 2 characters' });
}
if (!password || password.length < 8) {
return res.status(400).json({ error: 'Password must be at least 8 characters' });
}
next();
};
const createUser = async (req, res) => {
try {
const { email, name, password } = req.body;
// Check if user exists
const existing = await db.users.findOne({ email });
if (existing) {
return res.status(409).json({ error: 'User already exists' });
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 10);
// Create user
const user = await db.users.create({
email,
name,
password: hashedPassword,
createdAt: new Date()
});
// Don't return password
const { password: _, ...userWithoutPassword } = user;
res.status(201).json({
success: true,
data: userWithoutPassword
});
} catch (error) {
console.error('Create user error:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
200 - Success (GET, PUT, PATCH)201 - Created (POST)204 - No Content (DELETE)400 - Bad Request (validation failed)401 - Unauthorized (not authenticated)403 - Forbidden (not authorized)404 - Not Found409 - Conflict (duplicate)500 - Internal Server ErrorConsistent structure:
// Success
{
"success": true,
"data": { ... }
}
// Error
{
"error": "Error message",
"details": { ... } // optional
}
// List with pagination
{
"success": true,
"data": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 100
}
}
// Centralized error handler
app.use((err, req, res, next) => {
console.error(err.stack);
// Don't leak error details in production
const message = process.env.NODE_ENV === 'production'
? 'Internal server error'
: err.message;
res.status(err.status || 500).json({ error: message });
});
// Create
POST /api/resources
Body: { name, description }
// Read (list)
GET /api/resources?page=1&limit=20
// Read (single)
GET /api/resources/:id
// Update
PUT /api/resources/:id
Body: { name, description }
// Delete
DELETE /api/resources/:id
const getResources = async (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 20;
const skip = (page - 1) * limit;
const [resources, total] = await Promise.all([
db.resources.find().skip(skip).limit(limit),
db.resources.countDocuments()
]);
res.json({
success: true,
data: resources,
pagination: {
page,
limit,
total,
pages: Math.ceil(total / limit)
}
});
};
const getResources = async (req, res) => {
const { status, sort = '-createdAt' } = req.query;
const filter = {};
if (status) filter.status = status;
const resources = await db.resources
.find(filter)
.sort(sort)
.limit(20);
res.json({ success: true, data: resources });
};
/**
* @route POST /api/users
* @desc Create a new user
* @access Public
*
* @body {string} email - User email (required)
* @body {string} name - User name (required)
* @body {string} password - Password, min 8 chars (required)
*
* @returns {201} User created successfully
* @returns {400} Validation error
* @returns {409} User already exists
* @returns {500} Server error
*
* @example
* POST /api/users
* {
* "email": "[email protected]",
* "name": "John Doe",
* "password": "securepass123"
* }
*/
describe('POST /api/users', () => {
it('should create a new user', async () => {
const response = await request(app)
.post('/api/users')
.send({
email: '[email protected]',
name: 'Test User',
password: 'password123'
});
expect(response.status).toBe(201);
expect(response.body.success).toBe(true);
expect(response.body.data.email).toBe('[email protected]');
expect(response.body.data.password).toBeUndefined();
});
it('should reject invalid email', async () => {
const response = await request(app)
.post('/api/users')
.send({
email: 'invalid',
name: 'Test User',
password: 'password123'
});
expect(response.status).toBe(400);
expect(response.body.error).toContain('email');
});
});
@security-auditor - Security review@test-driven-development - Testing@database-design - Data modelingYou are a dependency security expert specializing in vulnerability scanning, license compliance, and supply chain security. Analyze project dependencies for known vulnerabilities, licensing issues, outdated packages, and provide actionable remediation strategies.
Perform language and framework specific security best-practice reviews and suggest improvements. Trigger only when the user explicitly requests security best practices guidance, a security review/report, or secure-by-default coding help. Trigger only for supported languages (python, javascript/typescript, go). Do not trigger for general code review, debugging, or non-security tasks.
Implement authentication and authorization with Better Auth - a framework-agnostic TypeScript authentication framework. Features include email/password authentication with verification, OAuth providers (Google, GitHub, Discord, etc.), two-factor authentication (TOTP, SMS), passkeys/WebAuthn support, session management, role-based access control (RBAC), rate limiting, and database adapters. Use when adding authentication to applications, implementing OAuth flows, setting up 2FA/MFA, managing user sessions, configuring authorization rules, or building secure authentication systems for web applications.
Package entire code repositories into single AI-friendly files using Repomix. Capabilities include pack codebases with customizable include/exclude patterns, generate multiple output formats (XML, Markdown, plain text), preserve file structure and context, optimize for AI consumption with token counting, filter by file types and directories, add custom headers and summaries. Use when packaging codebases for AI analysis, creating repository snapshots for LLM context, analyzing third-party libraries, preparing for security audits, generating documentation context, or evaluating unfamiliar codebases.
Perform language and framework specific security best-practice reviews and suggest improvements. Use when the user explicitly requests security best practices guidance, a security review or report, or secure-by-default coding help. Supports Python, JavaScript/TypeScript, and Go. Do NOT use for general code review, debugging, threat modeling (use security-threat-model), or non-security tasks.
Configures API gateways for routing, authentication, rate limiting, and request transformation in microservice architectures. Use when setting up Kong, Nginx, AWS API Gateway, or Traefik for centralized API management.
Implement secure API design patterns including authentication, authorization, input validation, rate limiting, and protection against common API vulnerabilities
You are a dependency security expert specializing in vulnerability scanning, license compliance, and supply chain security. Analyze project dependencies for known vulnerabilities, licensing issues, outdated packages, and provide actionable remediation strategies.
Take lingxling/api-endpoint-builder from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.