A web API defines how a client requests application operations and interprets their outcomes.
This lesson connects resource identifiers, HTTP methods, status codes and JSON to the controller, service and database boundaries already developed.
You will distinguish a representation from stored state and design predictable errors.
The local lab models a small task API: read a collection or item, create a task, replace an existing task and delete it.
It runs synchronous JavaScript only.
No network request, backend, account, authentication or database is involved.
🗺️
Resources
Give collections and items clear identifiers.
📨
Methods
Distinguish reads, creation, replacement and deletion.
📤
Responses
Match status, headers and body to the outcome.
🔎
Contracts
Validate JSON and conditional changes deliberately.
02
🔌An API Is an Application Contract
An API exposes controlled operations rather than direct database access.
A client sends an allowed request, the backend validates and authorizes it, application code performs its work, and a response describes the outcome.
The browser does not need database credentials to consume that contract.
A representation is a particular description of a resource, such as JSON for a task.
It is not necessarily a database row serialized without filtering.
Keep internal fields, secrets and implementation details out of public responses.
An endpoint returning JSON is not automatically a complete REST design.
It can be a useful HTTPAPI while still lacking architectural constraints or a consistent application protocol.
API boundary
🪟Client
Constructs a request.
🧭API handler
Validates and authorizes.
🧩Application
Coordinates the operation.
📤Representation
Returns accepted public data.
03
🧱REST Constraints and Practical HTTP APIs
REST describes an architectural style with constraints including client/server separation, stateless interactions, cacheability, a uniform interface and layered systems; code-on-demand is optional.
Resource identification, representations and meaningful protocol controls help clients interact predictably.
Stateless interaction means a request carries the context needed to understand it rather than depending on hidden conversational server state.
It does not mean a server has no database, a resource cannot change or every authentication design is identical.
Hypermedia links and controls can describe available application transitions.
Many practical APIs use only part of this style.
Describe their actual contract instead of claiming that plural paths plus JSON prove full REST compliance.
🪟
Client/server
Separate presentation and application responsibilities.
📨
Stateless request
Carry the needed interaction context.
📦
Cache rules
State whether a response can be reused.
🧭
Uniform interface
Use resources and protocol semantics deliberately.
The lab is intentionally a narrow HTTP resource model, not a complete REST or server implementation.
It provides no cache, hypermedia workflow or transport integration.
04
🗺️Collection and Item URLs
A collection URL such as /api/tasks identifies a set of tasks.
An item URL such as /api/tasks/1 identifies one task.
The route is an application identifier, not a promise about source filenames, framework classes or database table names.
Choose stable identifiers and a consistent path contract.
Query parameters can describe filtering or pagination for a collection, but arbitrary query fields should not silently become SQL fragments or privileged choices.
The lab has an exact collection path and canonical one-digit item IDs 1–9.
It rejects other paths as unknown.
It has no query parsing, URL normalization or encoded-path handling beyond that stated contract.
GET /api/tasks read collection
POST /api/tasks create a task
GET /api/tasks/1 read one task
PUT /api/tasks/1 replace existing task fields
DELETE /api/tasks/1 delete an existing task
Real APIs can support additional routes and creation semantics.
The toy item PUT updates existing tasks only; it does not create a missing item.
05
📨Methods, Safety and Idempotency
GET is a read with safe semantics: the client is not requesting a state-changing action.
A server can still log or collect operational metrics, so safe does not mean absolutely no incidental server activity.
Idempotency concerns the intended effect of repeating the same request, not identical status codes or response bodies.
PUT and DELETE have idempotent method semantics; POST does not provide that general guarantee.
Retrying a creation POST can create another resource.
A second DELETE can return 404 because the first removed the resource, while the deletion effect remains the same.
Conditional PUT can fail when the stored version changes without making an unsafe blind overwrite.
Method
Task operation
Important distinction
GET
Read collection/item
No requested mutation
POST
Create in collection
Repeated accepted request can create another item
PUT
Replace existing title/completed fields
Full accepted field set, not a partial patch
DELETE
Remove existing item
Repeated response may differ
PATCH is a separate method for partial modification with a defined patch format; the lab does not implement it.
HEAD and OPTIONS also remain outside its small router.
06
🧩JSON Syntax and Application Shape
JSON can represent objects, arrays, strings, numbers, booleans and null.
Object property names and string values use double quotes.
A syntactically valid JSON value can still be unacceptable application input.
The task body must be an object with exactly title and completed.
Title trims to 1–80 Unicode code points with no C0/C1 controls or unpaired surrogates; completed must be boolean.
The client cannot submit an ID, version, role or arbitrary extra field.
The lab parses JSON with JSON.parse after bounding the raw string to 1,000 JavaScript code units.
That parser can keep the last value for duplicate property names; it does not provide duplicate-key detection.
Real APIs should document or reject ambiguous payloads rather than assuming all parsers agree.
Numbers such as NaN and Infinity are not JSON numeric literals.
A JSON string "false" is also different from the boolean false required by this task contract.
07
🏷️Content-Type and Representation Expectations
Content-Type describes the representation carried in a message.
A JSONrequest should declare an appropriate JSON media type.
Accept expresses which response representations the client can receive; it is not a substitute for the request Content-Type.
The lab’s POST and PUT require exactly application/json.
It rejects another media type with 415 before parsing or changing a task.
This is a deliberately restricted teaching check, not a complete media-type parser or content-negotiation system.
GET and DELETE in this toy contract ignore the body and media-type controls.
A successful delete has no response body.
Clients should not always call a JSON parser regardless of status and representation.
POST /api/tasks
Content-Type: application/json
{"title":"Review HTTP","completed":false}
Expected accepted creation:
201 Created
Location: /api/tasks/3
Content-Type: application/json
The request text illustrates an HTTP contract; no request is sent when the lesson lab runs.
08
📤Status Codes, Location and Empty Bodies
Status codes distinguish outcomes instead of hiding every result inside a 200 body.
The lab uses 200 for accepted reads/replacement, 201 plus Location for creation and 204 with no body for successful deletion.
Unknown paths or missing items use 404.
Unsupported methods use 405 with Allow.
Invalid JSON or shape uses 400, unsupported media type 415, required missing precondition 428 and a stale accepted precondition 412.
These are the toy application’s explicit decisions.
A bounded collection reaching its capacity returns 409 here because creation conflicts with the toy store’s current limits.
A real system should define its own capacity/rate/availability behavior; those are not interchangeable errors.
✅
200 / 201
Accepted result or created resource.
📭
204
No response content to parse.
📨
400 / 415
Invalid representation or media type.
🔎
428 / 412
Required condition absent or no longer matching.
The lab clears old previews on every error. A stale task card must not make a failed change look successful.
09
🧭Validate Before Changing Application State
Routing and method checks determine the applicable operation.
For a JSON write, media type, syntax, size and shape validation precede mutation.
A creation limit and a conditional version check then decide whether accepted data can be applied.
A task’s ID is server-chosen in this model.
The accepted title/completed values are copied rather than sharing a caller-owned object.
Rejected requests allocate no ID and leave every stored task unchanged.
Validation is not authorization.
A title can be well-formed while the caller still lacks permission to edit that task.
This public fictional lab has no users or protected records and does not establish production access control.
Mutation gate
🗺️Route/method
Choose a known operation.
🧩Validate
Accept media type and data contract.
🔎Condition
Check limits or current item version.
💾Apply
Change only accepted task state.
In a real backend, version comparison and mutation must be coordinated atomically with database state.
A synchronous local function cannot demonstrate concurrent requests or distributed enforcement.
10
🔎ETag and Conditional Updates
An ETag is a representation validator.
A client can read an item, retain its validator and send If-Match when changing it.
If the current representation no longer matches, a server can reject the change rather than overwriting someone else’s work.
The lab gives item GET a strong teaching tag such as "task-1-v1".
PUT and DELETE require one exact quoted tag from this format; missing returns 428, malformed/unsupported syntax 400 and a well-formed mismatching tag 412.
It does not implement tag lists, wildcard or weak-validator rules.
A successful changed replacement advances the item version.
Replacing it with the same accepted fields leaves its version unchanged in this model.
After a change, GET the item again to obtain the new tag before another conditional write.
GET /api/tasks/1
→ 200, ETag: "task-1-v1"
PUT /api/tasks/1
If-Match: "task-1-v1"
Content-Type: application/json
{"title":"A changed title","completed":true}
GET again before editing with the new validator.
The toy PUT normalizes title text and returns a generated public representation, so it omits a responsevalidator rather than claiming the submitted bytes were saved unchanged.
The following GET supplies the current ETag.
An ETag is not a password or permission token.
11
📦Caching and Validators Are Different Decisions
A validator can support conditional interaction, while Cache-Control describes response reuse.
An ETag does not automatically mean a response should be cached.
Private or sensitive data needs a deliberate cache policy.
The lab marks every responseno-store so the teaching model does not imply a browser cache.
Its version checks demonstrate conditional changes, not cache revalidation.
It does not implement If-None-Match or 304.
For an actual API, design cache headers, freshness and validation together.
Avoid reusing a cached result as proof of authorization or assuming a stale client copy is always the latest server state.
🔎
Validator
Identify a representation version.
📦
Freshness
State when reuse is allowed.
🔒
Privacy
Protect user-specific response data.
🧪
Integration
Verify actual cache/proxy behavior.
The 428 response is not cacheable; this lab’s no-store policy also covers that outcome explicitly.
12
🪟Browser Fetch and Response Parsing
A received HTTP error response is different from a failed network request.
Fetch can resolve to a Response for an HTTP error, so a client must inspect its status and validate the intended representation rather than assuming resolution means success.
A 204 has no body.
Other successful JSON outcomes require a suitable Content-Type and acceptable data shape.
A parseable object is not automatically the model your UI expected.
The following client fragment is illustrative and is not called by the lab.
Its fetch requires a real same-origin backend route; this frontend course patch supplies no live /api/tasks service.
async function readTasks() {
const response = await fetch("/api/tasks");
if (!response.ok) {
throw new Error("Task read was not accepted");
}
const type = response.headers.get("Content-Type") || "";
if (type.split(";")[0].trim().toLowerCase() !== "application/json") {
throw new Error("Unexpected representation");
}
const data = await response.json();
// Validate data shape before presenting task rows.
return data;
}
A robust client should use an appropriate media-type check, controlled error display and response-model guard.
Render task titles as text, not interpreted HTML.
13
🌐CORS, Origins and Preflight
Browsers apply origin-based rules to script access.
CORS lets a server opt into certain cross-origin response access through headers; some requests trigger a preflight check.
It is a browser protocol, not a login mechanism.
A request using JSON or a custom header such as If-Match may require preflight across origins.
The backend needs an appropriate origin/method/header policy and must still authenticate and authorize operations.
Do not use no-cors as a way to read a blocked API: an opaque response cannot give the normal script access needed to read and validate its body.
CORS also does not protect a server against non-browser clients.
Separate permission boundaries
🪟Browser origin
Applies script access rules.
🌐CORS policy
Server declares allowed cross-origin access.
🔐Authentication
Establishes caller identity.
🛂Authorization
Checks the requested operation.
The local lab sends no requests or CORS preflights. Its behavior cannot prove Cloudflare/Render origin configuration.
14
🔐Authentication, Authorization and Error Design
Authentication establishes who the caller is; authorization determines what that caller may do.
A client-provided role, task ID or valid ETag is not sufficient proof of permission.
Check protected operations on the backend.
HTTPauthentication can use 401 with an appropriate challenge; 403 communicates refusal for a request the server will not authorize.
An API can also deliberately hide resource existence.
Choose a documented policy rather than exposing private records through inconsistent errors.
Keep public errors stable and useful without returning secrets or production stack traces.
A machine-readable error code and a controlled message can help the client choose an appropriate next step.
{
"error": {
"code": "stale_version",
"message": "Read the task again before changing it."
}
}
The next lesson develops Web Security. The task lab has no authentication and makes no claim of protecting real user data.
15
📄Pagination, Compatibility and Contract Tests
Bound collection results and specify stable ordering when an API grows beyond a small fixture.
Cursor or offset pagination must have a defined contract.
Adding filters should preserve the meaning of existing fields rather than silently changing accepted results.
Version breaking changes deliberately and document request fields, response fields, error behavior and limits.
Generated API descriptions can help tooling, but they do not replace tested examples and a correct backend implementation.
Retries need operation-specific rules.
Repeating POST creation can duplicate work; conditional PUT may reject a stale version; repeating DELETE may find the item already absent.
An idempotency mechanism needs actual backend enforcement, not just a client header.
📄
Bounded results
Specify order and pagination.
📦
Compatibility
Make contract changes deliberate.
🔄
Retries
Distinguish repeatable effects from duplicate work.
🧪
Documentation
Verify examples against behavior.
The lab deliberately limits active tasks to five, IDs to 1–9 and raw write input to 1,000 code units.
It has no pagination, persistent storage, retry cache or idempotency-key implementation.
Test routing, method Allow headers, invalid representations, accepted creation, full replacement, deletion and stale preconditions.
Check stored state before and after each rejection and avoid carrying an old successful preview into an error run.
For the real backend, separately verify HTTP serialization, body/header limits, atomic version enforcement, authentication, CORS, cache policy and concurrent requests.
Use controlled fixtures rather than publishing real credentials or private task data in traces.
The lab checks local JavaScript state transitions and safe rendering only.
The visualizer follows one accepted creation; the interactive controls let you examine reads, writes, errors and preconditions.
📨
Rejected input
No ID allocation or state mutation.
✅
Accepted write
Controlled outcome and public representation.
🔎
Stale condition
Reject without overwriting current state.
🌐
Transport
Verify real headers/network independently.
Next: Level 28 — Web Security.
Keep the distinction between a predictable APIcontract and actual security enforcement clear.
16
🔄Premium Visualizer — An API Resource Request
Follow an accepted task creation through routing, validation, state change, response and safe presentation. This approved five-stage player explains the request contract without sending HTTP.
API RESOURCE REQUEST TRACE
Step 1 of 5
🗺️
STEP 01
Identify the resource operation
POST to the task collection requests creation.
POST /api/tasks
What is happening?
A collection write differs from item read/replacement/deletion.
17
🧪Premium Interactive — A Local Task API Contract
This synchronous JavaScript model runs no network, server, authentication or database.
Its in-memory task collection starts with task1 Review HTTP methods and task2 Practise JSON <objects>, both incomplete.
Only completion uses local storage.
Collection: GET reads, POST creates.
Item: GET reads, PUT replaces exactly title/completed, DELETE removes.
POST/PUT require exact application/json and a JSON object with exactly title (trimmed 1–80 Unicode code points, no controls/lone surrogates) and completed (boolean).
Raw input is bounded to 1,000 JavaScript code units.
PUT/DELETE require the exact current single strong mock ETag.
Read GET first and copy the quoted ETag into If-Match.
Missing is 428; malformed/unsupported syntax 400; stale is 412.
PUT normalizes data and omits responseETag; read again for the new tag.
DELETE 204 has no body or Content-Type.
At most five active tasks and monotonic IDs1–9 are allowed.
Accepted repeated POST can create another task; deleted IDs are not reused.
Reset clears all task state and restores the original fixture.
The limited router, media check and tag format are not full HTTP implementations.
Idle. Local JavaScript API model; no HTTP request sent.
Current mock resource state · versions are internal teaching data
Simulated request
No request yet.
Decision trace
No trace yet.
Response status and headers
No response yet.
Response body · displayed literally
No response body yet.
Safe outcome preview
No result yet.
18
🛠️Debugging — Inspect the First Rejection
🗺️
Route/method
Compare exact path and Allow before assuming body failure.
🧩
Representation
Check media type, syntax, keys and value types.
🔎
Condition
Read the current tag instead of overwriting a changed task.
📤
Empty body
A204 is complete without JSON content.
If a create succeeds twice, inspect whether the client retried a non-idempotent POST.
If PUT fails with 412, read the current task and decide how to reconcile changes rather than deleting the precondition blindly.
If parsing fails after deletion, check the status before reading JSON.
If the screen still shows an older task after an error, clear the previous preview and display the rejected outcome.
The lab is not a debugger for a deployed backend, CORS policy or authentication system.
Verify those boundaries with real requests separately.
19
💬Interview Questions — Flip to Explain
QUESTION
Is every JSON endpoint fully RESTful?
Click or press Enter to explain
ANSWER
No. REST has architectural constraints beyond JSON and resource-looking paths; describe the actual API contract.
QUESTION
What does idempotency mean?
Click or press Enter to explain
ANSWER
Repeating the same request has the same intended effect; status and response body need not be identical.
QUESTION
Why can repeated accepted POST create duplicate work?
Click or press Enter to explain
ANSWER
POST does not provide a general idempotent creation guarantee; a separate enforced retry policy may be needed.
QUESTION
What does Content-Type describe?
Click or press Enter to explain
ANSWER
The representation in the message; Accept describes what response representations the client can receive.
QUESTION
Why return201 with Location after creation?
Click or press Enter to explain
ANSWER
It communicates creation and identifies the created resource in this contract.
QUESTION
Why should a204 not be parsed as JSON?
Click or press Enter to explain
ANSWER
It has no response content; the client must handle the completed empty outcome.
QUESTION
What does a stale If-Match check prevent in this model?
Click or press Enter to explain
ANSWER
It prevents replacing/deleting a task whose current version no longer matches the supplied condition.
QUESTION
Does CORS authenticate a caller?
Click or press Enter to explain
ANSWER
No. It controls browser cross-origin access; authentication and authorization remain separate backend checks.
20
❓MCQ Practice — Explain API Outcomes
PRACTICE
1. Which URL identifies the task collection?
PRACTICE
2. Which operation creates a task in this lab?
PRACTICE
3. What does idempotency describe?
PRACTICE
4. Which type is completed in an accepted task body?
PRACTICE
5. Which header identifies the created resource?
PRACTICE
6. What content does a204 deletion return?
PRACTICE
7. What does this lab return for unsupported methods?
PRACTICE
8. What happens on a well-formed stale If-Match?
PRACTICE
9. What happens when the required If-Match is absent?
PRACTICE
10. What does the successful normalized PUT do about a response validator?
PRACTICE
11. What does CORS provide?
PRACTICE
12. Does this local model verify real HTTP/CORS/concurrency?
21
💻Extra Practice — Follow a Resource Lifecycle
📚
Read
GET collection:200, two tasks. GET /api/tasks/1:200 with quoted tag task-1-v1.
🆕
Create
POST collection with New task/false:201, Location /api/tasks/3, three stored items. Repeat: another item.
🔄
Replace
PUT item1 with changed fields and tagv1:200, version2 internally, no responseETag. GET again for tagv2.
🔎
Stale update
Repeat changed PUT with old tagv1:412 and unchanged current task.
📭
Delete
DELETE item1 with current tag:204 and empty body. Repeat:404; no additional mutation.
🧩
Bad input
Try invalid JSON, completed as string, extra ID or text/plain on POST. Expect400/415 and no allocation.
🏷️
Required condition
Empty If-Match on PUT/DELETE:428. Malformed tag:400. Valid tag for another version/item:412.
🛡️
Literal text
Create title <Demo> & API. It remains text in JSON/preview. Reset restores original task state.
22
📌Quick Revision
🗺️Resource: Collection and item identifiers.
📨Method: Read/create/replace/delete contract.
🧩JSON: Syntax and application shape differ.
🏷️Media type: Describe message representation.
📤Outcome: Status, headers and body agree.
📭204: Completed empty response.
🔎Conditional write: Avoid overwriting stale versions.
📦Caching: Validator and reuse policy differ.
🌐CORS: Browser access, not identity.
🧪Integration: Verify actual transport/security separately.
23
📖Glossary — Flip to Learn
TERM
Web API
Click to see meaning
DEFINITION
Web API
An application interface accessed through web requests and responses.
TERM
Resource
Click to see meaning
DEFINITION
Resource
A concept identified and interacted with through the application protocol.
TERM
Representation
Click to see meaning
DEFINITION
Representation
A particular description of resource state, such as JSON.
TERM
REST
Click to see meaning
DEFINITION
REST
An architectural style with defined distributed-system constraints.
TERM
Safe method
Click to see meaning
DEFINITION
Safe method
A method whose requested semantics are read-only.
TERM
Idempotency
Click to see meaning
DEFINITION
Idempotency
The same intended effect when an identical request is repeated.
TERM
Content-Type
Click to see meaning
DEFINITION
Content-Type
Metadata describing the representation carried by a message.
TERM
ETag
Click to see meaning
DEFINITION
ETag
A validator identifying a representation version.
TERM
If-Match
Click to see meaning
DEFINITION
If-Match
A request condition requiring a matching current representation validator.
TERM
CORS
Click to see meaning
DEFINITION
CORS
A browser protocol for controlled cross-origin response access.
24
🏆Final Challenge — Specify a Task API
Write a collection/item contract with methods, exact accepted input, status/headers/body and bounded results.
Separate client representations from internal state, and define what repeated creation or deletion does.
Require deliberate conditions for protected replacements, with a real atomic version check and a defined stale-update outcome.
Validate title/completed and render titles as text; do not accept role or ID fields as permission.
Test invalid syntax/type/media,404/405,201+Location,204 empty content, stale conditions and state preservation after rejection.
Separately verify actual HTTP, authentication, authorization, CORS, cache policy and concurrent updates.
Success criterion: predict both response and stored state for every accepted and rejected operation.
Next: Level28 — Web Security.
25
✅Level 27 Complete?
Explain resource/method/representation distinctions, reproduce creation/replacement/deletion and stale preconditions, and handle204 without JSON parsing. Identify the actual transport/security checks the local lab cannot perform. Completion is a local study marker.