ข้ามไปยังเนื้อหา

Middleware

Express middleware คือ (req, res, next) => void เรียก next() เพื่อส่งต่อ หรือเรียก res.json() เพื่อจบ request เลย ส่วน Echo ใช้แนวคิด pipeline เดียวกันแต่อาศัย error-return pattern และ closure ของ Go:

// Middleware signature ของ Echo
func(next echo.HandlerFunc) echo.HandlerFunc

Middleware คืน HandlerFunc ใหม่ที่ wrap next ไว้ เรียก next(c) เพื่อส่งต่อ หรือคืน error เพื่อยกเลิก

TypeScript
// Express middleware
function requestLogger(req, res, next) {
console.log(`${req.method} ${req.path}`);
next();
}
app.use(requestLogger);
Go
// Echo middleware
func RequestLogger(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
fmt.Printf("%s %s\n", c.Request().Method, c.Request().URL.Path)
return next(c) // ส่งต่อ
}
}
e.Use(RequestLogger)

Echo มี middleware พร้อมใช้งานใน production หลายตัวใน sub-package middleware

TypeScript
// Express — ต้องการ package ภายนอก
import morgan from 'morgan';
import cors from 'cors';
app.use(morgan('combined'));
app.use(cors({ origin: '*' }));
// ไม่มี recover built-in — ต้องใช้ express-async-errors หรืออื่น ๆ
Go
// Echo built-in — ไม่ต้องการ package เพิ่ม
import "github.com/labstack/echo/v4/middleware"
e.Use(middleware.Logger()) // log request แบบ structured ไปยัง stdout
e.Use(middleware.Recover()) // จับ panic คืน 500
e.Use(middleware.CORS()) // default: อนุญาตทุก origin
// จำกัด CORS เฉพาะ origin ที่ระบุ:
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"https://example.com"},
AllowMethods: []string{http.MethodGet, http.MethodPost},
}))

เหมือน Express ลำดับมีความสำคัญ middleware ที่ลงทะเบียนก่อนจะทำงานก่อน Logger และ Recover ควรอยู่ชั้นนอกสุดเสมอ

e.Use(middleware.Logger()) // 1 — log ทุก request
e.Use(middleware.Recover()) // 2 — จับ panic จาก handler ที่ตามมา
e.Use(authMiddleware) // 3 — ตรวจสอบ auth หลังจาก logging ตั้งค่าแล้ว

ใน Express คุณส่ง middleware เข้าไปที่ route ได้ตรง ๆ ส่วน Echo ทำแบบเดียวกันได้ด้วย .Use บน group

TypeScript
// Express — per-route middleware
app.get('/admin', authMiddleware, adminHandler);
// Express — router-level
const adminRouter = express.Router();
adminRouter.use(authMiddleware);
adminRouter.get('/', adminHandler);
app.use('/admin', adminRouter);
Go
// Echo — per-route middleware
e.GET("/admin", adminHandler, authMiddleware)
// Echo — group-level middleware
admin := e.Group("/admin")
admin.Use(authMiddleware)
admin.GET("", adminHandler)
admin.GET("/users", adminUsersHandler)
TypeScript
// Express JWT-like auth middleware
function requireAuth(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ message: 'unauthorized' });
try {
req.user = verifyToken(token);
next();
} catch {
res.status(401).json({ message: 'invalid token' });
}
}
Go
// Echo custom auth middleware
func RequireAuth(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
header := c.Request().Header.Get("Authorization")
if header == "" {
return echo.NewHTTPError(http.StatusUnauthorized, "missing token")
}
parts := strings.SplitN(header, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
return echo.NewHTTPError(http.StatusUnauthorized, "bad token format")
}
claims, err := verifyToken(parts[1])
if err != nil {
return echo.NewHTTPError(http.StatusUnauthorized, "invalid token")
}
// เก็บ claims ใน context สำหรับ handler ที่ตามมา
c.Set("user", claims)
return next(c)
}
}

รันบนเครื่องของคุณ — ต้องการ Echo module และ network port

ฟังก์ชัน Echo middleware มี signature แบบใด?
Built-in middleware ใดที่จับ panic และคืน response 500?
ใช้วิธีใดในการ apply middleware เฉพาะ route group?