Personal Catalogue: React, Express & MongoDB — Chapter 4, Exercise 3 ===================================================================== TASK The required flags on the Book and Cd form fields (author, artist) only produce a browser-level warning if left empty. Explain why this doesn't replace the backend's own required: true validation from Chapter 2, and describe a real request that would bypass the frontend's check entirely. SOLUTION The required attribute on is a browser feature, not a server guarantee. It runs entirely inside the user's own browser, at the moment a real
element attempts to submit -- the browser inspects the DOM, sees an empty required field, and blocks the submit event before handleSubmit ever runs, showing a native validation message. That check has no way to reach the actual server. It only exists in the one specific browser tab where the form is rendered, and only applies if the request is actually generated by submitting that literal element through the DOM's own submit mechanism. A request that bypasses it entirely: curl -X POST http://localhost:4000/api/items \ -H "Content-Type: application/json" \ -d '{"itemType":"Cd","title":"Untitled Album"}' This never touches the React form, the browser's required attribute, or handleSubmit at all -- it's a raw HTTP request built by curl, sent directly to the real API. No artist field is present, and nothing on the client side is involved to stop it. What actually stops it is Chapter 2's own Cd discriminator schema: const cdSchema = new mongoose.Schema({ artist: { type: String, required: true }, tracklist: [String], }, options); Model.create() runs full schema validation regardless of who or what sent the request -- the browser form, a curl command, a different frontend entirely, or a bug in this very React app. Missing artist fails with a real Mongoose ValidationError, caught by Chapter 3's own try/catch and returned as a 400 with a real error message, exactly the same response the form's own alert(error) already displays when validation fails. WHY THIS WORKS AS AN ANSWER ---------------------------- It identifies precisely where the browser's required check actually runs (inside form-submission handling, in one browser tab) and why that scope can never extend to a request that skips the form entirely, then demonstrates a real, working request that does exactly that, and names the actual enforcement mechanism -- Chapter 2's own schema-level required: true, checked on every create() call no matter its origin -- rather than treating "the backend also validates" as an unverified claim.