نوشتن Middleware در Express.js: راهنمای کامل برای توسعه‌دهندگان

Middleware در Express.js یکی از مهم‌ترین مفاهیم برای کنترل جریان درخواست‌ها، افزودن قابلیت‌ها، اعتبارسنجی، لاگ‌گیری، مدیریت خطا و ساخت معماری‌های ماژولار است. Middlewareها به سه عنصر اصلی دسترسی دارند: req، res و next. این توابع می‌توانند درخواست را تغییر دهند، پاسخ را ارسال کنند، یا کنترل را به middleware بعدی بسپارند. این مقاله تمام مفاهیم کلیدی Middleware—از ساخت ساده‌ترین نمونه تا Middlewareهای async، مدیریت خطا، و Middlewareهای قابل پیکربندی—را به‌صورت کامل و کاربردی توضیح می‌دهد.

Express Middlewarenext()Request-Response CycleAsync MiddlewareError HandlingConfigurable Middleware

~3 دقیقه مطالعه • بروزرسانی ۵ دی ۱۴۰۴

1. Middleware در Express چیست؟


Middleware تابعی است که به سه چیز دسترسی دارد:

  • req: شیء درخواست
  • res: شیء پاسخ
  • next: تابعی برای انتقال کنترل به middleware بعدی

Middleware می‌تواند:

  • هر نوع کدی اجرا کند
  • req یا res را تغییر دهد
  • چرخهٔ درخواست–پاسخ را خاتمه دهد
  • یا با next() کنترل را منتقل کند

اگر یک middleware چرخهٔ درخواست–پاسخ را پایان ندهد، حتماً باید next() را صدا بزند، در غیر این صورت درخواست معلق می‌ماند.

2. یک مثال ساده


const express = require('express')
const app = express()

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(3000)

در ادامه سه middleware به این برنامه اضافه می‌کنیم.

3. Middleware اول: myLogger


این middleware یک پیام ساده در کنسول چاپ می‌کند.

const myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

برای فعال‌سازی:

app.use(myLogger)

نکات مهم:

  • ترتیب بارگذاری middleware اهمیت دارد.
  • اگر بعد از route قرار گیرد، اجرا نمی‌شود.
  • next() کنترل را به middleware بعدی می‌دهد.

4. Middleware دوم: requestTime


این middleware یک ویژگی جدید به req اضافه می‌کند.

const requestTime = function (req, res, next) {
  req.requestTime = Date.now()
  next()
}

استفاده:

app.use(requestTime)

app.get('/', (req, res) => {
  res.send(`Requested at: ${req.requestTime}`)
})

5. Middleware سوم: validateCookies (Async)


این middleware کوکی‌ها را اعتبارسنجی می‌کند. اگر نامعتبر باشند، خطا ایجاد می‌شود.

async function validateCookies (req, res, next) {
  await cookieValidator(req.cookies)
  next()
}

در Express 5، اگر یک middleware async خطا بدهد، next(error) به‌صورت خودکار فراخوانی می‌شود.

استفاده همراه با cookie-parser:

app.use(cookieParser())
app.use(validateCookies)

app.use((err, req, res, next) => {
  res.status(400).send(err.message)
})

نکتهٔ مهم: اگر چیزی به next() بدهید (به‌جز 'route' یا 'router')، Express آن را خطا تلقی می‌کند.

6. Middlewareهای قابل پیکربندی


برای ساخت middleware قابل تنظیم، یک تابع صادر کنید که options بگیرد و middleware بسازد.

my-middleware.js

module.exports = function (options) {
  return function (req, res, next) {
    // Use options here
    next()
  }
}

استفاده:

const mw = require('./my-middleware')
app.use(mw({ option1: '1', option2: '2' }))

نمونه‌های واقعی: cookie-session، compression

7. نکات کلیدی درباره Middleware


  • Middlewareها به ترتیب تعریف اجرا می‌شوند.
  • اگر next() فراخوانی نشود، درخواست معلق می‌ماند.
  • Middlewareهای async در صورت خطا به‌طور خودکار next(error) را فراخوانی می‌کنند.
  • می‌توان req و res را تغییر داد.
  • می‌توان چرخهٔ درخواست–پاسخ را پایان داد.
  • می‌توان middlewareهای ماژولار و قابل پیکربندی ساخت.

نتیجه‌گیری


Middleware قلب معماری Express است. با استفاده از آن می‌توان لاگ‌گیری، اعتبارسنجی، مدیریت خطا، افزودن ویژگی‌های جدید به req و res، و ساخت ساختارهای ماژولار را به‌سادگی انجام داد. با درک کامل این مفهوم، می‌توان اپلیکیشن‌هایی انعطاف‌پذیر، قابل نگهداری و حرفه‌ای ساخت.

نوشته و پژوهش شده توسط دکتر شاهین صیامی