Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Form submission: validate on the server and return field errors

Last updated: 4 Oct 20266 min read
tutorial
IntermediateBy AITrove Editorial

Browser validation helps users correct mistakes before a request, but the server owns the stored-data contract. A client can omit required controls, change hidden values, or call the endpoint directly. A server must parse within size limits, validate each field, authorize the operation, and return errors that can be attached to named controls. The example accepts a case number and a short inspection note. It returns a field-error object without mutating the record map when either field is invalid. The browser page should render an overall error summary and retain safe submitted values, allowing correction rather than forcing re-entry. This lesson separates syntax validation from permission checks; passing one does not imply the other.

Case study

A report for case 47 with an empty note returns status 422 and an error keyed to note. A report for case 47 with 'seal replaced' returns status 201 and stores that text. A caller who supplies a negative case number is rejected before storage. A hidden case number in a form is still caller-controlled and must be checked against the authorized case on the server. If a write succeeds but the response is lost, a blind retry might duplicate a side effect; a durable idempotency contract is separate from the field checks shown here.

Working contract

javascript
const inspections = new Map();
function saveInspection(input) {
  const errors = {};
  if (!Number.isInteger(input.caseId) || input.caseId < 1) {
    errors.caseId = "Choose a valid case";
  }
  if (typeof input.note !== "string" || !input.note.trim() || input.note.length > 160) {
    errors.note = "Write a note of at most 160 characters";
  }
  if (Object.keys(errors).length) return { status: 422, errors };
  const note = input.note.trim();
  inspections.set(input.caseId, note);
  return { status: 201, caseId: input.caseId };
}
console.log(saveInspection({ caseId: 47, note: " " }).status);
console.log(saveInspection({ caseId: 47, note: "seal replaced" }).status);
console.log(inspections.get(47));

Observed output

Output
422
201
seal replaced

Cost and tradeoffs

Validation scans the note once, taking O(L) time for note length L. The sample in-memory map uses expected O(1) lookup and update, with O(N) stored records. Parsing an unbounded body would break the stated cost and memory model, so a real server needs a request-size cap before decoding. Returning every field error in one response can reduce repeated round trips compared with revealing only one error at a time. Escaping is required when safe values and messages are rendered back into HTML; server validation does not sanitize arbitrary output contexts automatically.

Common Mistakes

  • Do not trust client-side required attributes as the only validation layer.
  • Do not trust a hidden case ID as authorization evidence.
  • Do not discard safe submitted values after a 422 response.
  • Do not retry an ambiguous write without an idempotency or reconciliation rule.

Continue through the stack

HTML constraint validation: improve feedback without trusting the browser; HTML form help: connect visible instructions and errors to a control; HTML forms: choose GET for retrieval and POST for a state change; HTTP requests: keep method, status, and body contracts separate.

Broader connections

Relational Records and Database Constraints; Idempotent Write Requests and Lost Responses.

Failure trace

A browser field has required and maxlength, so the team skips server checks. A direct HTTP client submits a whitespace-only note of 4,000 characters, and it reaches storage. Browser constraints improve interaction but cannot protect the database. Parse and bound the request body, validate field rules server-side, then return field-specific errors while preserving safe values the person already entered.

Verification

  • Submit an empty note through the browser and through a direct request; both must be rejected.
  • Send a body beyond the configured size limit and confirm it is stopped before storage work.
  • Return two field errors and verify their messages are connected to the controls and focus path.

Decision note

Validation rules belong where the trusted write happens. Duplicate a small subset in the browser for fast feedback, but keep the server rule authoritative and version it with the API contract.

Further connections

Forms and Data Entry Workflows; Native Form Submission and Progressive Enhancement; Asynchronous Field Validation Races.

Further connections

Form-Associated Custom Controls and Native Fallback.

web-tech
web-development
Storage details