Skip to content
On this page

Middleware

Middleware functions process requests before they reach route handlers.

Basic Middleware

typescript
import { server } from "verb"

const app = server.http()

// Middleware function
const logger = (req, res, next) => {
  console.log(`${req.method} ${req.url}`)
  next()
}

// Apply globally
app.use(logger)

Middleware Order

Middleware runs in the order it's defined:

typescript
app.use((req, res, next) => {
  console.log("First")
  next()
})

app.use((req, res, next) => {
  console.log("Second")
  next()
})

app.get("/", (req, res) => {
  res.send("Handler")
})

// Output: First, Second, Handler

Route-Specific Middleware

Apply middleware to specific routes:

typescript
const auth = (req, res, next) => {
  if (!req.headers.authorization) {
    return res.status(401).json({ error: "Unauthorized" })
  }
  next()
}

app.get("/public", (req, res) => {
  res.send("Public")
})

app.get("/private", auth, (req, res) => {
  res.send("Private")
})

Multiple Middleware

Chain multiple middleware on a route:

typescript
app.get("/admin",
  authenticate,
  requireRole("admin"),
  logAccess,
  (req, res) => {
    res.send("Admin area")
  }
)

Async Middleware

typescript
const loadUser = async (req, res, next) => {
  const token = req.headers.authorization?.split(" ")[1]
  if (token) {
    req.user = await getUserFromToken(token)
  }
  next()
}

app.use(loadUser)

Built-in Middleware

typescript
import { middleware } from "verb"

// CORS
app.use(middleware.cors({
  origin: "https://example.com",
  methods: ["GET", "POST"]
}))

// Request logging
app.use(middleware.logger())

// Rate limiting
app.use(middleware.rateLimit({
  windowMs: 60000,
  max: 100
}))

Error Handling Middleware

Error middleware has 4 parameters:

typescript
const errorHandler = (err, req, res, next) => {
  console.error(err)
  res.status(500).json({
    error: err.message
  })
}

// Must be last
app.use(errorHandler)

Modifying Request/Response

typescript
// Add data to request
app.use((req, res, next) => {
  req.startTime = Date.now()
  next()
})

// Modify response
app.use((req, res, next) => {
  const originalJson = res.json.bind(res)
  res.json = (data) => {
    data.timestamp = new Date().toISOString()
    return originalJson(data)
  }
  next()
})

Released under the MIT License.