Good Code
The good version validates the body once at the route boundary and only passes trusted values into the service.
Lesson 04
Validate request input at the route boundary before calling business services.
import { Router } from "express";
import { parseCreateReviewBody } from "./validation";
export function createReviewsRouter(service: ReviewsService) {
const router = Router();
router.post("/", async (req, res) => {
// Validate at the route edge before calling business logic.
const result = parseCreateReviewBody(req.body);
if (!result.ok) {
res.status(400).json({ error: result.error });
return;
}
const review = await service.createReview(result.value);
res.status(201).json({ data: review });
});
return router;
}import { Router } from "express";
export function createReviewsRouter(service: ReviewsService) {
const router = Router();
router.post("/", async (req, res) => {
// Raw body fields reach the service without shape checks.
const review = await service.createReview({
title: req.body.title,
reviewerIds: req.body.reviewerIds,
dueDate: req.body.dueDate,
});
res.status(201).json(review);
});
return router;
}The good version validates the body once at the route boundary and only passes trusted values into the service.
The bad version copies raw body fields directly into business logic and leaves missing, malformed, or extra input to fail later.