Design an Endpoint
The mini design round sounds casual: "Design an API for managing candidate transcripts." It isn't casual. The interviewer is watching whether you clarify before you design, whether your resources are nouns, and whether you know the boring conventions cold. Strong candidates ask two or three questions first: Who consumes it β our own MVC front end, another agency system, or the public? What's the read/write ratio? Are records ever deleted, or only superseded? Public-sector bonus: asking about retention and audit requirements before designing DELETE says you've worked with real records.
Resources, verbs, and the shape of the answer
Talk in resources: /api/v1/candidates/{id}/transcripts and
/api/v1/transcripts/{id}. Verbs map to methods β GET (safe, cacheable), POST (create,
not idempotent), PUT (full replace, idempotent), PATCH (partial), DELETE. Say the word
idempotent and use it correctly; it's a checklist item in most rubrics. When an operation
isn't a clean noun ("reissue a transcript"), don't invent POST /doVerification β model it
as a sub-resource or action resource: POST /transcripts/{id}/reissues.
Status codes are where sloppy candidates leak: 200 vs 201 (+ Location header) vs
204 for deletes; 400 validation vs 401 unauthenticated vs 403 unauthorized vs 404;
409 for conflicts; 422 if the team uses it for semantic validation. Name
ProblemDetails (RFC 7807) as the error body β it's the ASP.NET Core default and shows
you return machine-readable errors, not ad-hoc JSON.
Paging, versioning, and the follow-ups
Any list endpoint gets the follow-up: "There are 400,000 rows β now what?" Answer with
paging as a contract: ?page=2&pageSize=50 plus a response envelope with totalCount,
or cursor/keyset paging when offset paging gets slow deep into the set β tie it back to
the EF module (Skip on page 8,000 still counts rows). Always cap pageSize server-side,
and support sort/filter parameters with an allowlist, not raw column names.
For versioning, know the three options β URL segment (/v1/), query string, header β
and have a position: URL versioning is the most visible and cache-friendly, and
Asp.Versioning packages make any of them mechanical. The senior move is saying you version
only on breaking changes, and additive fields aren't breaking.
Answers that fall flat
- Verbs in routes (
/getCandidateById), everything returned as200including errors. - Designing without asking a single question about consumers or scale.
- No paging on list endpoints, or
pageSizeunbounded because "the client will be sensible."
Practice prompts
- Design
transcriptsend to end aloud in five minutes: questions, routes, codes, paging, versioning. - List the exact status code for: duplicate create, expired auth cookie, valid auth but wrong agency, malformed date.
- Argue keyset paging over offset paging for an auditor's export of 400k records.