First, the essential ideas
- REST and resource
- Representational State Transfer, REST, is an architectural style using resource representations and a uniform interface. A resource is the thing identified by a URI; a JSON body can represent it but is not the resource itself.
- HTTP request and response
- A request has a method, target and headers, with a body when applicable. A response has a status, headers and possibly a body. Transport success does not guarantee application success.
- CRUD
- Create, read, update and delete describe data operations. APIs commonly use POST for create, GET for read, PUT or PATCH for update and DELETE for removal, but the documented resource contract decides exact behavior.
- Stateless request
- Each request supplies the context needed to understand it. Stateless interaction does not mean that the server stores no resources, authorization data or other persistent information.
- Authentication and authorization
- Authentication establishes identity or credential possession. Authorization determines permitted actions. A valid credential can still lack permission to change a device.
- Safe and idempotent methods
- A safe method does not request a state change. Idempotent means repeated identical requests have the same intended server effect as one, not that every response is identical or that the operation is harmless.
- Representation headers
- Accept states the response formats a client can handle. Content-Type describes the format of the body being sent. They answer different questions and must match the API contract.
Read an HTTP exchange as a small evidence bundle. The method says what was requested, the URI says where, the headers describe context, and the response says how that request was handled. Looking only for a JSON brace skips most of the useful information.
See the idea
One local request, three kinds of evidence
The URI chooses the target; status, headers and content explain what the server actually returned.
Request the resource
curl sends GET /device.json to the loopback listener. The fixture reads the local synthetic file, not a router.
What this model leaves out: This is the declared local file-server path, not an authenticated REST platform. No remote router, credential exchange or CRUD write is shown.
Full visual explanation and references
The curl client sends a request over loopback to the local HTTP fixture. The fixture reads device.json and returns status, headers and content to curl.
This is the declared local file-server path, not an authenticated REST platform. No remote router, credential exchange or CRUD write is shown.
- Request the resource
curl sends GET /device.json to the loopback listener. The fixture reads the local synthetic file, not a router.
www.rfc-editor.org - Inspect the response
Read the status and headers before interpreting the returned content. A successful file read is not live device evidence.
www.rfc-editor.org - Repair the wrong path
GET /missing.json produces a not-found response. Restore /device.json and repeat the same check without changing credentials or permissions.
www.rfc-editor.org
One idea at a time
Start with something familiar.
Start with one exact URL: http://127.0.0.1:8056/device.json. The scheme is HTTP, the host is this VM's loopback, the port is 8056, and the path identifies a local synthetic file. No actual router is queried.
Why learn this?
An automation script can receive a response and still fail because the path, method, credentials or body is wrong. Keeping those dimensions separate helps diagnose a failure without broadening permissions or repeatedly sending a write.
An everyday comparison
A service desk request names the item, the action and the requester. The receipt can say accepted, completed, refused or not found. Receiving a receipt is not the same as receiving the requested service.
What happens in a network
The URI identifies a resource, the method selects an operation and the response describes its handling. A 202 response can mean accepted for later work; a follow-up task check may be needed.
Where the comparison stopsHTTP codes have specified semantics and APIs have exact contracts. A human clerk may infer missing intent, while a server can reject a malformed or unauthorized request even when its purpose seems obvious.
Follow one worked example
- Read the complete baseline exchange.
GET /device.json should return a successful status and a synthetic JSON representation. The file's enabled value is data, not live interface state.
Why: A body must be understood in the context of its source, freshness and status.
- Change only the resource path.
GET /missing.json should return 404 while the same server remains reachable. That is different from connection refused.
Why: A wrong path is a safe fault that separates HTTP handling from network reachability.
- Restore the path and inspect again.
Returning to /device.json should recover the original response. A POST test is explicitly unsupported and should not create anything.
Why: Method capability must come from the documented implementation, not a memorized CRUD slogan.
Your first small task
For a hypothetical documented interface API, compare GET /interfaces/1 with PUT /interfaces/1 and PATCH /interfaces/1. Mark which reads, which may replace and which requests a partial change. Do not execute those writes anywhere.
Show a hint
Update is not a single universal verb, and repeating a write is not automatically safe.
Check the expected result
GET reads. PUT usually creates or replaces the target representation under its contract. PATCH applies a defined partial change. The exact body and allowed fields need documentation.
Pause and explain it in your own words
Does a 200 response containing JSON prove a router interface is operationally up?
Show a hint
Ask what resource was queried and whether the fields describe configuration or observed state.
Show the explanation
No. The response might represent desired configuration, cached data or a synthetic fixture. Verify the resource model, timestamp and operational field, then use the relevant device or traffic evidence.
Short answer
What should you understand today?
REST APIs expose resources through defined interactions, commonly over HTTP. Read the method, exact URI, authentication requirement, status, headers and body together. GET reads; POST, PUT, PATCH and DELETE have different documented effects. A successful connection or a JSON-looking body alone does not prove a request succeeded.
Before you begin
Learning targets
- Understand IP addresses, TCP ports and the difference between a client and server.
- Use a disposable offline Ubuntu 24.04 VM with Python 3.12 and curl 8.x already installed.
- Use only synthetic data; the fixture has no authentication or TLS and must stay bound to 127.0.0.1.
- Explain resources, representations, statelessness and common CRUD method mappings.
- Distinguish Basic, bearer tokens, API keys and authorization without exposing secrets.
- Interpret status, headers and response content before deciding what happened.
- Run a loopback baseline, wrong-path fault, repair, retest and explicit server shutdown.
Words you will meet
Open a word when you need its meaning. You do not need to memorize the whole list before reading.
REST and resource
Representational State Transfer, REST, is an architectural style using resource representations and a uniform interface. A resource is the thing identified by a URI; a JSON body can represent it but is not the resource itself.
HTTP request and response
A request has a method, target and headers, with a body when applicable. A response has a status, headers and possibly a body. Transport success does not guarantee application success.
CRUD
Create, read, update and delete describe data operations. APIs commonly use POST for create, GET for read, PUT or PATCH for update and DELETE for removal, but the documented resource contract decides exact behavior.
Stateless request
Each request supplies the context needed to understand it. Stateless interaction does not mean that the server stores no resources, authorization data or other persistent information.
Authentication and authorization
Authentication establishes identity or credential possession. Authorization determines permitted actions. A valid credential can still lack permission to change a device.
Safe and idempotent methods
A safe method does not request a state change. Idempotent means repeated identical requests have the same intended server effect as one, not that every response is identical or that the operation is harmless.
Representation headers
Accept states the response formats a client can handle. Content-Type describes the format of the body being sent. They answer different questions and must match the API contract.
REST is more than JSON over a URL
REST describes resource-oriented interactions using representations and a uniform interface, with client-server separation, stateless requests, cache semantics and layered systems. Not every HTTP endpoint is fully RESTful. A server can keep resource state while each request carries the context needed for processing. JSON is one representation format, not a transport protocol or a requirement that every API must use.
- A URI identifies the target; a representation describes it at a particular time.
- RESTCONF is a specific network-management protocol using modeled data, not another name for all HTTP.
Match CRUD intent to the documented method
GET retrieves a representation; HEAD asks for corresponding response metadata without a response body. POST often creates a subordinate resource or invokes an operation. PUT creates or replaces the target according to its contract. PATCH applies a defined partial modification. DELETE requests removal of the target. GET and HEAD are safe; PUT and DELETE are idempotent in intended effect, but that does not make deletion harmless. POST and PATCH are not universally idempotent.
- Do not send an incomplete PUT body when the API treats it as replacement.
- The fixture's unsupported POST result is not a successful create demonstration.
Authenticate without confusing permission
Basic authentication encodes a user and password; Base64 is not encryption. Bearer authentication presents a token whose possession permits its scoped use, so it must be protected. Some APIs use an API key in a documented header; others issue tokens through an authorization flow. Use TLS with certificate validation for real credentials. Authentication success does not establish permission for every resource or method.
- Do not use curl -k as a routine fix for an untrusted server certificate.
- Store and rotate secrets using the organization's approved mechanism, not hardcoded lesson examples.
Interpret status and metadata together
Successful 2xx responses differ: 200 commonly includes a representation, 201 signals creation, 202 may indicate asynchronous acceptance, and 204 has no response content. A 400 suggests a bad request; 401 concerns authentication; 403 refuses the action; 404 means the target was not found or its existence is not disclosed. A 5xx response indicates a server-side inability to fulfill the request. Read the documented error body and request identifiers without leaking secrets.
- Inspect actual Content-Type before parsing the body as JSON.
- Accept describes desired response formats; request Content-Type describes the submitted body.
Use a bounded local fixture for HTTP mechanics
Python's simple server serves files and supports GET and HEAD, not arbitrary CRUD writes. Binding it to 127.0.0.1 limits this demonstration to the VM's loopback. A new temporary directory prevents accidental exposure of unrelated files. The synthetic device.json is a teaching fixture, not an export of a real device. An offline VM and proxy bypass keep all requests on the declared local path.
- A full authenticated API practical requires a separately authorized platform and its resource schema.
- No paid service, sandbox credential or production API is needed for this exercise.
Map the lesson without inventing exam coverage
This chapter covers v1.1 6.5 instruction: REST characteristics, authentication types, CRUD and HTTP verbs, and data encoding concepts. JSON structure is developed in Day 57. The announced v2.0 does not name the same standalone REST objective, so the material is supporting automation knowledge, not a claim that a new objective has been satisfied. Current v1.1 remains active through 2 February 2027; v2.0 starts 3 February.
- A local validator verifies authored structure, not HTTP runtime or API permissions.
- Keep expected results separate from the transcript you actually observe.
Real-world walkthrough
A script receives a response but reads the wrong thing
In a fictional operations tool, an inventory URL changes. The script still reaches the server but gets an HTML 404 page. It tries to parse that page as JSON and reports a generic network failure. Repeated credential changes do not help because authentication was never the demonstrated problem.
- Record the method and redacted URI, then distinguish a transport error from an HTTP response.
- Inspect the status and Content-Type before attempting JSON parsing.
- Compare the resource path with the versioned API contract and identify the changed path.
- Repair only that path in a nonproduction test, then verify status and expected representation fields.
- Add explicit error handling and avoid blind write retries; preserve a redacted request identifier where available.
Guided GNS3 lab
Read an HTTP exchange on loopback only
Use an actual local file server and curl to inspect a synthetic response, produce a wrong-path fault, repair it and observe an unsupported method. No authenticated REST service or device runtime is claimed.
Addressing plan
| Device | Interface | Address | Purpose |
|---|---|---|---|
| HTTP fixture | lo; TCP listener | 127.0.0.1:8056 | Serves synthetic device.json locally. |
| curl client | lo; ephemeral source port | 127.0.0.1 | Local client; the OS selects its source TCP port. |
Set up the lab
- Open two Terminal windows from the VM console and label them A and B. Keep the VM external adapter disconnected.
- Use a new temporary directory with only the synthetic fixture. Do not serve a home directory or add credentials.
- If port 8056 is occupied, stop and identify your own conflicting process; do not terminate an unknown service.
- With no local runtime, hand-annotate the request and predicted response and mark the exercise paper-only.
Prepare a synthetic representation
In VM console Terminal A, check Python and create a new temporary directory. Enter each command separately. The shell variable LAB56 stays in this Terminal A session for later cleanup.
python3 --version
LAB56=$(mktemp -d /tmp/ccna56.XXXXXX)
cd "$LAB56"
python3 -c 'import json,pathlib; pathlib.Path("device.json").write_text(json.dumps({"name":"R56","enabled":True}), encoding="utf-8")'
pwdWhat each command means
python3 --version- Record the actual interpreter version.
LAB56=$(mktemp -d /tmp/ccna56.XXXXXX)- Create a uniquely named empty directory owned by this exercise.
cd "$LAB56"- Move into that directory before writing or serving anything.
python3 -c 'import json,pathlib; pathlib.Path("device.json").write_text(json.dumps({"name":"R56","enabled":True}), encoding="utf-8")'- Write only a synthetic JSON fixture; Python serializes True as JSON true.
pwd- Record the exact exercise directory for cleanup verification.
- What you should see
- Expect a new directory containing device.json with synthetic fields.
- Why this step matters
- Creating data locally avoids exporting device state or exposing unrelated files.
Start the loopback listener
In the same VM console Terminal A, start the foreground server from the fixture directory. Leave this terminal running; use Terminal B for clients. Do not replace loopback with an all-interface address.
python3 -m http.server 8056 --bind 127.0.0.1What each command means
python3 -m http.server 8056 --bind 127.0.0.1- Serve the current fixture directory on TCP 8056 bound only to loopback.
- What you should see
- Expect the listener to start; if it reports address in use, stop and resolve the local conflict.
- Why this step matters
- The explicit bind and isolated directory define the exact exposure boundary.
Read the baseline response
In VM console Terminal B, inspect curl's version and send a bounded GET. Proxy bypass ensures even a configured proxy is not used for this local exercise.
curl --version
curl --noproxy '*' --max-time 5 -i http://127.0.0.1:8056/device.jsonWhat each command means
curl --version- Record the actual client version.
curl --noproxy '*' --max-time 5 -i http://127.0.0.1:8056/device.json- GET the fixture; -i displays response headers and body, --max-time bounds waiting.
- What you should see
- Expect 200 and the synthetic JSON body; record actual headers and protocol version rather than assuming them.
- Why this step matters
- Status, headers and body belong together when interpreting the response.
Compare HEAD with GET
In VM console Terminal B, request metadata for the same target. Do not mistake the absent response body for missing JSON; HEAD intentionally differs from GET in that respect.
curl --noproxy '*' --max-time 5 -I http://127.0.0.1:8056/device.jsonWhat each command means
curl --noproxy '*' --max-time 5 -I http://127.0.0.1:8056/device.json- Send HEAD and display response headers without requesting a response body.
- What you should see
- Expect a successful status and metadata without the JSON body.
- Why this step matters
- A method's semantics explain the result more reliably than looking only for text content.
Introduce a safe path fault
In VM console Terminal B, change only the target path to a nonexistent file. The server, port and method remain unchanged. Compare the result with a transport failure in your notes.
curl --noproxy '*' --max-time 5 -i http://127.0.0.1:8056/missing.jsonWhat each command means
curl --noproxy '*' --max-time 5 -i http://127.0.0.1:8056/missing.json- Request a nonexistent resource while keeping the known listener unchanged.
- What you should see
- Expect HTTP 404 and an error representation, not connection refused.
- Why this step matters
- This isolates resource lookup from TCP reachability and credential questions.
Repair the path and verify the boundary
In VM console Terminal B, restore the known path and then test one unsupported POST against the same local fixture. This server has no create handler; do not label the POST a CRUD deployment.
curl --noproxy '*' --max-time 5 -i http://127.0.0.1:8056/device.json
curl --noproxy '*' --max-time 5 -i -X POST http://127.0.0.1:8056/device.json
curl --noproxy '*' --max-time 5 -i http://127.0.0.1:8056/device.jsonWhat each command means
curl --noproxy '*' --max-time 5 -i http://127.0.0.1:8056/device.json- Repeat the baseline GET after correcting the path.
curl --noproxy '*' --max-time 5 -i -X POST http://127.0.0.1:8056/device.json- Ask the file handler for an unsupported method; no production endpoint is contacted.
curl --noproxy '*' --max-time 5 -i http://127.0.0.1:8056/device.json- Verify that the readable fixture still exists after the rejected method.
- What you should see
- Expect restored GET success, unsupported POST 501 and unchanged GET content.
- Why this step matters
- A server's implemented methods determine behavior; a generic CRUD table cannot create missing capabilities.
Stop and clean up the local fixture
In VM console Terminal A, press Ctrl+C to stop only the foreground Python server. Then verify the recorded directory before deleting its single fixture and removing the now-empty directory. Retest from Terminal B afterward.
pwd
rm -- device.json
cd /tmp
rmdir -- "$LAB56"What each command means
pwd- Confirm Terminal A is still in the exact recorded /tmp/ccna56 directory.
rm -- device.json- Remove only the synthetic file in the verified exercise directory.
cd /tmp- Leave the directory before removing it.
rmdir -- "$LAB56"- Remove only the now-empty directory stored by this same shell session.
- What you should see
- Expect the listener stopped and only the exercise file/directory removed. In Terminal B repeat the baseline curl; expect connection failure, not HTTP 404.
- Why this step matters
- Process shutdown and filesystem cleanup are distinct; no broad deletion or unknown process termination is needed.
Verify
- Record Python and curl versions and the loopback bind address.
- Keep the baseline status, headers and synthetic fields together.
- Compare HEAD without content, wrong-path 404 and restored GET.
- Label POST 501 as unsupported by this fixture, not an authentication result.
- After stopping the server, repeat the exact bounded curl from Terminal B and record connection failure; no runtime is asserted here.
Troubleshoot
- If curl cannot connect, inspect the foreground server, bind address and port before discussing HTTP statuses.
- If 404 appears, compare the exact path and server working directory; do not rotate credentials in this unauthenticated fixture.
- If the body is HTML, read the status and Content-Type before feeding it to a JSON parser.
- If real API TLS validation fails in a separate lab, repair trust and naming; do not normalize disabling certificate checks.
GNS3 does not provide Cisco images. A license or entitlement must permit the image in the selected environment; do not share or redistribute image files. Cisco Modeling Labs is an official alternative. Its supplied Cisco reference images are licensed for use within CML, not automatically for export to GNS3. An unlicensed learner must use the explicitly labeled paper alternative, not report simulated Cisco execution.
- Stop the foreground server with Ctrl+C in Terminal A.
- Verify the exact temporary directory, delete only device.json and use rmdir on the empty exercise directory.
- Keep redacted observations; no credential or real device data should exist in this lab.
Practice set
Answer before you reveal
01What does Accept describe?
Content-Type instead describes a transmitted body's format. The two fields are not interchangeable.
02Why is Basic authentication not encryption?
Use protected transport with certificate validation for real credentials and keep them out of shared evidence.
03Does idempotent mean harmless?
Idempotence concerns repeated intended effect, not risk level, permission or identical response status.
04Why can curl finish normally on HTTP 404?
Inspect the status or use an appropriate failure policy in a script instead of assuming an exit alone proves application success.
05What does a bearer token require?
Possession can enable access, so never publish the token or place it in a demonstration URL.
06What API functions were not implemented by the fixture?
The practical teaches HTTP evidence only. Explain the remaining concepts without fabricating successful runtime output.
Knowledge check
Quiz: prove the reasoning
Keep these
Technical takeaways
- Read method, target, status, headers and body together.
- CRUD mappings require the resource's actual contract.
- Stateless interaction does not prohibit stored resource state.
- Authentication and authorization answer different questions.
- Base64 is not encryption and bearer tokens are secrets.
- A file server is not a full authenticated REST device API.
