# Middleware Patterns

> >

- **Type:** Skill
- **Install:** `agentstack add skill-versoxbt-claude-initial-setup-middleware-patterns`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [VersoXBT](https://agentstack.voostack.com/s/versoxbt)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [VersoXBT](https://github.com/VersoXBT)
- **Source:** https://github.com/VersoXBT/claude-initial-setup/tree/main/skills/express-node/middleware-patterns
- **Website:** https://github.com/VersoXBT/claude-initial-setup#installation

## Install

```sh
agentstack add skill-versoxbt-claude-initial-setup-middleware-patterns
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Express Middleware Patterns

Patterns for building robust Express.js middleware chains.

## When to Use
- User is setting up an Express.js application middleware stack
- User needs authentication or authorization middleware
- User asks about rate limiting, CORS, or request validation
- User is debugging middleware execution order
- User needs to write custom middleware

## Core Patterns

### Middleware Execution Order

Middleware executes in the order it is registered. Order matters: authentication must run before authorization, and error handlers must be last.

```typescript
import express from 'express'

const app = express()

// 1. Built-in middleware
app.use(express.json({ limit: '10kb' }))
app.use(express.urlencoded({ extended: true }))

// 2. Security / CORS
app.use(corsMiddleware)

// 3. Rate limiting
app.use(rateLimiter)

// 4. Request logging
app.use(requestLogger)

// 5. Routes (with route-specific middleware)
app.use('/api/v1/auth', authRoutes)
app.use('/api/v1/users', authenticate, userRoutes)
app.use('/api/v1/admin', authenticate, authorize('admin'), adminRoutes)

// 6. 404 handler
app.use(notFoundHandler)

// 7. Error handler (must be last, must have 4 parameters)
app.use(errorHandler)
```

### Authentication Middleware

Verify tokens and attach user context to the request object.

```typescript
import { Request, Response, NextFunction } from 'express'
import jwt from 'jsonwebtoken'

interface AuthRequest extends Request {
  user?: { id: string; role: string }
}

function authenticate(req: AuthRequest, res: Response, next: NextFunction): void {
  const header = req.headers.authorization
  if (!header?.startsWith('Bearer ')) {
    res.status(401).json({ error: 'Missing authorization header' })
    return
  }

  const token = header.slice(7)
  try {
    const payload = jwt.verify(token, process.env.JWT_SECRET!) as { id: string; role: string }
    req.user = { id: payload.id, role: payload.role }
    next()
  } catch {
    res.status(401).json({ error: 'Invalid or expired token' })
  }
}

function authorize(...roles: string[]) {
  return (req: AuthRequest, res: Response, next: NextFunction): void => {
    if (!req.user || !roles.includes(req.user.role)) {
      res.status(403).json({ error: 'Insufficient permissions' })
      return
    }
    next()
  }
}
```

### Rate Limiting

Protect endpoints from abuse. Use different limits for different routes.

```typescript
import rateLimit from 'express-rate-limit'

const globalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,  // 15 minutes
  max: 100,
  standardHeaders: true,
  legacyHeaders: false,
  message: { error: 'Too many requests, try again later' },
})

const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,                     // Strict limit for auth endpoints
  message: { error: 'Too many login attempts' },
})

app.use(globalLimiter)
app.use('/api/v1/auth/login', authLimiter)
```

### CORS Configuration

Configure Cross-Origin Resource Sharing for frontend clients.

```typescript
import cors from 'cors'

const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || []

const corsMiddleware = cors({
  origin: (origin, callback) => {
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  },
  methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
  maxAge: 86400,
})
```

### Request Validation Middleware

Validate request body, query, and params using Zod. Create a reusable factory.

```typescript
import { z, ZodSchema } from 'zod'
import { Request, Response, NextFunction } from 'express'

function validate(schema: {
  body?: ZodSchema
  query?: ZodSchema
  params?: ZodSchema
}) {
  return (req: Request, res: Response, next: NextFunction): void => {
    const errors: Record = {}

    if (schema.body) {
      const result = schema.body.safeParse(req.body)
      if (!result.success) errors.body = result.error.flatten()
    }
    if (schema.query) {
      const result = schema.query.safeParse(req.query)
      if (!result.success) errors.query = result.error.flatten()
    }
    if (schema.params) {
      const result = schema.params.safeParse(req.params)
      if (!result.success) errors.params = result.error.flatten()
    }

    if (Object.keys(errors).length > 0) {
      res.status(400).json({ error: 'Validation failed', details: errors })
      return
    }
    next()
  }
}

// Usage
const CreateUserSchema = z.object({
  name: z.string().min(1).max(100),
  email: z.string().email(),
})

router.post('/users', validate({ body: CreateUserSchema }), createUser)
```

## Anti-Patterns

- **Forgetting to call `next()`** -- Every middleware must call `next()` or send a response. Forgetting causes the request to hang indefinitely.
- **Error handler with 3 parameters** -- Express only recognizes error middleware if it has exactly 4 parameters: `(err, req, res, next)`. Three parameters means it is treated as regular middleware.
- **Registering error handlers before routes** -- Error handlers must come after all routes and other middleware. Express routes to the first matching handler.
- **Blocking the event loop in middleware** -- Synchronous CPU-heavy operations (bcrypt with high rounds, large JSON parsing) block all requests. Use async alternatives or worker threads.
- **Applying auth middleware globally when some routes are public** -- Apply auth selectively to protected route groups, not to the entire app.

## Quick Reference

```
Middleware signature:  (req, res, next) => void
Error middleware:      (err, req, res, next) => void

Order: parsing -> security -> rate-limit -> logging -> routes -> 404 -> errors

Route-specific:  router.get('/path', middleware1, middleware2, handler)
Router-level:    router.use(middleware)
App-level:       app.use(middleware)
```

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [VersoXBT](https://github.com/VersoXBT)
- **Source:** [VersoXBT/claude-initial-setup](https://github.com/VersoXBT/claude-initial-setup)
- **License:** MIT
- **Homepage:** https://github.com/VersoXBT/claude-initial-setup#installation

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-versoxbt-claude-initial-setup-middleware-patterns
- Seller: https://agentstack.voostack.com/s/versoxbt
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
