home / skills / aidotnet / moyucode / express-api

express-api skill

/skills/community/express-api

This skill generates production-ready Express.js REST APIs in TypeScript with middleware, validation, error handling and authentication patterns.

npx playbooks add skill aidotnet/moyucode --skill express-api

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
4.3 KB
---
name: express-api
description: 生成Express.js REST API,包含TypeScript、中间件、验证、错误处理和认证模式。
metadata:
  short-description: 生成Express.js REST API
---

# Express API Skill

## Description
Generate Express.js REST APIs with TypeScript and best practices.

## Trigger
- `/express` command
- User requests Express API
- User needs Node.js backend

## Prompt

You are an Express.js expert that creates production-ready APIs.

### Express App Setup

```typescript
// src/app.ts
import express, { Express, Request, Response, NextFunction } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import morgan from 'morgan';
import { router } from './routes';
import { errorHandler } from './middleware/errorHandler';

const app: Express = express();

// Middleware
app.use(helmet());
app.use(cors({ origin: process.env.CORS_ORIGIN, credentials: true }));
app.use(morgan('combined'));
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));

// Routes
app.use('/api/v1', router);

// Health check
app.get('/health', (req, res) => {
  res.json({ status: 'ok', timestamp: new Date().toISOString() });
});

// Error handling
app.use(errorHandler);

export { app };
```

### Router with Controllers

```typescript
// src/routes/users.ts
import { Router } from 'express';
import { UserController } from '../controllers/UserController';
import { validate } from '../middleware/validate';
import { authenticate } from '../middleware/auth';
import { CreateUserSchema, UpdateUserSchema } from '../schemas/user';

const router = Router();
const controller = new UserController();

router.get('/', authenticate, controller.getAll);
router.get('/:id', authenticate, controller.getById);
router.post('/', validate(CreateUserSchema), controller.create);
router.put('/:id', authenticate, validate(UpdateUserSchema), controller.update);
router.delete('/:id', authenticate, controller.delete);

export { router as userRouter };
```

### Controller

```typescript
// src/controllers/UserController.ts
import { Request, Response, NextFunction } from 'express';
import { UserService } from '../services/UserService';
import { AppError } from '../utils/AppError';

export class UserController {
  private userService = new UserService();

  getAll = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { page = 1, limit = 10 } = req.query;
      const users = await this.userService.findAll({
        page: Number(page),
        limit: Number(limit),
      });
      res.json(users);
    } catch (error) {
      next(error);
    }
  };

  getById = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const user = await this.userService.findById(req.params.id);
      if (!user) {
        throw new AppError('User not found', 404);
      }
      res.json(user);
    } catch (error) {
      next(error);
    }
  };

  create = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const user = await this.userService.create(req.body);
      res.status(201).json(user);
    } catch (error) {
      next(error);
    }
  };
}
```

### Error Handler Middleware

```typescript
// src/middleware/errorHandler.ts
import { Request, Response, NextFunction } from 'express';
import { AppError } from '../utils/AppError';

export function errorHandler(
  err: Error,
  req: Request,
  res: Response,
  next: NextFunction
) {
  console.error(err);

  if (err instanceof AppError) {
    return res.status(err.statusCode).json({
      error: {
        code: err.code,
        message: err.message,
      },
    });
  }

  res.status(500).json({
    error: {
      code: 'INTERNAL_ERROR',
      message: 'An unexpected error occurred',
    },
  });
}
```

### Validation Middleware

```typescript
// src/middleware/validate.ts
import { Request, Response, NextFunction } from 'express';
import { ZodSchema } from 'zod';

export function validate(schema: ZodSchema) {
  return (req: Request, res: Response, next: NextFunction) => {
    const result = schema.safeParse(req.body);
    if (!result.success) {
      return res.status(400).json({
        error: {
          code: 'VALIDATION_ERROR',
          details: result.error.errors,
        },
      });
    }
    req.body = result.data;
    next();
  };
}
```

## Tags
`express`, `nodejs`, `api`, `rest`, `backend`

## Compatibility
- Codex: ✅
- Claude Code: ✅

Overview

This skill generates production-ready Express.js REST APIs using TypeScript, with common middleware, request validation, structured error handling, and authentication patterns. It scaffolds routes, controllers, services, and reusable middleware so you get a consistent, maintainable server foundation. The output emphasizes safety, observability, and developer ergonomics for Node.js backends.

How this skill works

The generator produces a TypeScript Express app wired with security and utility middleware (helmet, cors, morgan) plus JSON/body parsing and a health endpoint. It scaffolds routers that map to controller methods, creates validation middleware using Zod schemas, and provides a centralized error handler that distinguishes application errors from internal failures. Authentication and validation are applied at the route level and controllers invoke services for business logic, returning consistent HTTP responses.

When to use it

  • Building a new REST API in Node.js with TypeScript and want a best-practices starter
  • Scaffolding CRUD endpoints with validation, auth, and centralized error handling
  • Creating a consistent project structure for teams to reduce onboarding friction
  • Prototyping APIs that require input validation and clear error semantics
  • Standardizing middleware and logging across multiple microservices

Best practices

  • Keep controllers thin: delegate business logic to services to simplify testing
  • Validate inputs at the boundary using Zod and return structured validation errors
  • Use an AppError class for expected errors and let the error handler map status codes
  • Protect sensitive routes with an authenticate middleware and role checks where needed
  • Limit request body size and enable helmet/cors/morgan for security and observability

Example use cases

  • User management API with paginated list, get-by-id, create, update, and delete endpoints
  • Internal microservice exposing CRUD operations with consistent error shapes for consumers
  • Prototype an MVP backend quickly while preserving production patterns like auth and validation
  • Educational example for teams learning to separate controllers, services, and middleware

FAQ

How are validation errors returned?

Validation uses Zod; failures return HTTP 400 with a VALIDATION_ERROR code and detailed field errors.

How should I handle authentication and roles?

Use the authenticate middleware for protected routes and extend it or add a separate authorization middleware to enforce role-based checks.