Validating input
Check every field on the server, and survive a request that arrives twice.
Never trust what arrives in req.body. The browser form can be skipped completely: anyone can send any JSON with curl or Postman. Check every field on the server before you use it.
{"ok":true,"value":{"name":"Divya","mobile":"9876543210","year":3}}
{"ok":false,"errors":["name must be at least 2 letters","mobile must be a 10-digit Indian number","year must be 1 to 5"]}The result keeps only the fields you expect. Saving req.body straight into the database would let someone add isAdmin: true. Change the mobile number and run it again.
app.post("/api/applications", async (req, res) => {
const result = validateApplication(req.body);
if (!result.ok) return res.status(400).json({ errors: result.errors });
const saved = await saveApplication(result.value);
res.status(201).json(saved);
});Libraries such as zod do the same job with less code once you have many forms. Checks in the browser still help users fix mistakes quickly, but they are not security.
The same request, twice
On a slow network, people press the button again, and phones retry by themselves. For anything that charges money or sends a message, the browser sends a random request id with the first try, and the server ignores a second request with an id it has already handled.