Skip to lesson content
Web Technologies › Level 27
LEVEL 27 · WEB APIs + REST

Web APIs and REST

Design predictable resource requests, representations and response outcomes.

☕ Java web📨 HTTP methods🧩 JSON contracts🧪 Lab + MCQs
01

Learning Objectives

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 HTTP API 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.

MethodTask operationImportant distinction
GETRead collection/itemNo requested mutation
POSTCreate in collectionRepeated accepted request can create another item
PUTReplace existing title/completed fieldsFull accepted field set, not a partial patch
DELETERemove existing itemRepeated 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.

{
  "title": "Review HTTP methods",
  "completed": false
}

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 JSON request 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 response validator 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 response no-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.

HTTP authentication 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 API contract 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 response ETag; 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 response ETag. 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.