Context: you already have the MVC starter shown in the prompt. For these tasks, make changes only in routes/student_routes.js. Do not modify controllers, schemas, or server.js. Keep changes minimal and focused on route-level middleware.
-
Do not remove existing functionality. You can change how routes are declared to attach middleware, but keep the same endpoints working.
-
Define new middleware functions inside
routes/student_routes.jsabove the route registrations. -
Register middleware on specific routes only.
-
Use Postman for checks. Steps are provided.
Goal: add a route-level middleware that verifies the :id path parameter looks like a MongoDB ObjectId beforecalling the controller. If the format is wrong, respond with 400 Bad Request and a short JSON message. Otherwise call next().
-
A function
validateObjectId(req, res, next)that checksreq.params.id. -
If
idis not a 24-character hex string, immediately returnres.status(400).json({ msg: "Invalid id format" }). -
If valid, call
next(). -
Attach this middleware only to
GET /api/students/:id.
-
Add the middleware function above your route definitions in
routes/student.js. -
Replace the existing
api.route(":id").get(getOneStudent);with a route that includes the middleware.
// Route-level middleware: validateObjectId
function validateObjectId(req, res, next) {
// TODO 1: read id from req.params
// TODO 2: check that it is 24 hex chars (0-9, a-f, A-F)
// Hint: use a simple regex or length + hex test
// TODO 3: if invalid, return res.status(400).json({ msg: "Invalid id format" })
// TODO 4: otherwise, next()
}
// Attach it to the :id GET route (replace your current line for :id)
// api.get(":id", validateObjectId, getOneStudent);Valid id case
-
In Postman, create a GET request to
http://localhost:5000/api/students/<put-a-real-24-hex-id-here>. -
Send the request. If the id exists, you should get
200 OKwith the student. If it does not exist, your controller will return404as before. In both cases, the middleware should allow the request through.
Invalid id case
-
Send a GET to
http://localhost:5000/api/students/123. -
Expected:
400 Bad Requestand JSON{ "msg": "Invalid id format" }. -
Your controller should not run for this case.
Goal: show that route-level middleware can be composed. Add two middlewares to the POST route only: one that enforces an API key in a custom header, and one that normalizes request data before it reaches the controller.
-
An API key is just a shared secret checked by the server.
-
For this exercise, the key will be read from the
x-api-keyrequest header. -
You can hardcode a value like
classroom-secretor read fromprocess.env.API_KEYif you prefer. -
If the header is missing or wrong, respond with
401 Unauthorizedand do not callnext().
-
enforceApiKey(req, res, next)-
Read the header with
req.header("x-api-key"). -
Compare it to the expected key.
-
If missing or mismatched, respond
401with{ msg: "Missing or invalid API key" }. -
Otherwise call
next().
-
-
normalizeStudentBody(req, res, next)-
Trim whitespace on
first_nameandlast_nameif they exist inreq.body. -
Optionally uppercase the first letter of each name for consistency.
-
If
ageexists, ensure it is a number (e.g., convert withNumber(...)) but do not add new validation rules beyond that. -
Call
next().
-
-
Attach both middlewares to only the POST route, in this order:
enforceApiKeythennormalizeStudentBody, then your existing controllercreateStudent.
-
Add both middleware functions above your route definitions in
routes/student_routes.js. -
Update the POST registration to include both functions.
// Route-level middleware: enforce API key via x-api-key header
function enforceApiKey(req, res, next) {
// TODO 1: read the key from req.header("x-api-key")
// TODO 2: compare to expected value (e.g., process.env.API_KEY or "classroom-secret")
// TODO 3: if missing or invalid, return res.status(401).json({ msg: "Missing or invalid API key" })
// TODO 4: otherwise next()
}
// Route-level middleware: normalize incoming student data
function normalizeStudentBody(req, res, next) {
// TODO 1: if req.body.first_name exists, trim it and normalize casing
// TODO 2: if req.body.last_name exists, trim it and normalize casing
// TODO 3: if req.body.age exists, convert it to a Number
// TODO 4: next()
}
// Attach them to the POST route (replace your current "/" POST line)
// api.post("/", enforceApiKey, normalizeStudentBody, createStudent);Positive path
-
Create a new POST request to
http://localhost:5000/api/students. -
In Headers, add
Content-Type: application/jsonandx-api-key: classroom-secret(or your chosen key). -
In Body, choose
rawandJSON, then paste:
{
"first_name": " ada ",
"last_name": " lovelace ",
"email": "ada@love.com",
"age": "28"
}- Send the request. Expected:
201 Created. The controller runs. Your normalizer should trim names and coerceageto a number before it reaches the controller.
Missing or wrong key
-
Remove or change the
x-api-keyheader and resend. -
Expected:
401 Unauthorizedand{ "msg": "Missing or invalid API key" }. The controller should notrun.
-
Exercise 1 blocks bad
:idformats with a clear 400 response. Valid formats pass through to the controller. -
Exercise 2 composes two middlewares on the POST route. Requests with a valid key proceed, and data is normalized before the controller.
-
Changes are limited to
routes/student_routes.js. Controllers, schemas, andserver.jsremain untouched.