Validate ObjectId Middleware
The Validate ObjectId Middleware ensures that route parameters intended to be MongoDB ObjectIds are valid before the request reaches your controller. This prevents CastError exceptions from Mongoose and ensures strictly typed ID handling.
It is designed to be:
- Robust: Checks for valid 24-character hex strings using Mongoose's
isValidObjectId. - Flexible: Can validate any route parameter name (defaults to
id). - Clean: Throws a standardized
ApiErrorif validation fails.
Installation Guide
Install the component using the ServerCN CLI:
npx servercn add validate-objectIdPrerequisites
This middleware relies on mongoose for validation and an error handling utility for throwing exceptions.
Dependencies
- Mongoose: For
isValidObjectId. - Api Error Handler: implementation of
ApiErrorclass.
Basic Implementation
1. MVC Structure
src/middlewares/validate-id.ts
import { Request, Response, NextFunction } from "express";
import { isValidObjectId } from "mongoose";
import { ApiError } from "../utils/api-error";
/**
* Middleware to validate MongoDB ObjectId
* @param paramName - The name of the parameter to validate (default: "id")
*/
export const validateObjectId = (paramName: string = "id") => {
return (req: Request, res: Response, next: NextFunction) => {
const value =
req.params[paramName] || req.body[paramName] || req.query[paramName];
if (!value) {
throw ApiError.badRequest(`${paramName} is required`);
}
if (!isValidObjectId(value)) {
throw ApiError.badRequest(`Invalid ${paramName}`);
}
next();
};
};2. Feature Structure
src/shared/middlewares/validate-id.ts
import { Request, Response, NextFunction } from "express";
import { isValidObjectId } from "mongoose";
import { ApiError } from "../errors/api-error";
export const validateObjectId = (paramName: string = "id") => {
return (req: Request, res: Response, next: NextFunction) => {
const value =
req.params[paramName] || req.body[paramName] || req.query[paramName];
if (!value) {
throw ApiError.badRequest(`${paramName} is required`);
}
if (!isValidObjectId(value)) {
throw ApiError.badRequest(`Invalid ${paramName}`);
}
next();
};
};Usage Example
Apply the middleware to any route that contains an :id parameter.
import { Router } from "express";
import { validateObjectId } from "../middlewares/validate-id";
import { getUserById, deleteUser } from "../controllers/user.controller";
const router = Router();
// Validates 'id' param by default
router.get("/:id", validateObjectId(), getUserById);
// Validates custom param name 'userId'
router.delete("/:userId", validateObjectId("userId"), deleteUser);
export default router;Why Use This?
Without this middleware, passing an invalid ID (e.g., 123) to a Mongoose query like findById causes a CastError, which might crash your app or result in a generic 500 Internal Server Error if not handled properly. This middleware catches the issue early and returns a proper 400 Bad Request.