The Language of the Web
architect, critique, revise, codeModule 2: The Language of the Web (JSON & Status Codes)
Goal: Accept incoming structured payloads and return correct status indicators.
What you need to know first
JSON (JavaScript Object Notation): The text-based standard for structured data payloads. It represents lists (arrays) and dictionaries (objects) as text:
{
"title": "Study Python",
"hours": 2.5
}
HTTP Status Codes:
- 2xx (Success): E.g.
200 OK(general success) or201 Created(new resource saved). - 4xx (Client Error): E.g.
400 Bad Request(payload missing parameters) or404 Not Found. - 5xx (Server Error): E.g.
500 Internal Server Error(your code crashed).
The SOLO idea
Clean APIs never crash (returning 500 error logs) when users send bad data. You must intercept inputs at the route boundary, validate their types, and return descriptive 4xx client errors. To ensure all inputs are guarded, plan the validator schema before writing the endpoint.
Lab 2: Validated POST Request
Estimated AI conversations: 2-3
-
Run the server (
python main.py). -
Step A: Plan validation boundaries. Open Copilot Chat and type:
Follow #file:workflows/architect.md — Plan a POST endpoint at
/tasksinmain.pythat accepts a JSON body with keystitle(string) andhours(float).- If
titleis empty, return a JSON error message with status code400 Bad Request. - If
hoursis negative, return a JSON error message with status code400 Bad Request. - Otherwise, return a JSON message containing the keys and a status code
201 Created.
- If
-
Step B: Critique boundaries. In the same conversation, type:
Follow #file:workflows/critique.md — Critique the validation plan. What happens if the user sends letters in the
hoursfield? What if the field is missing entirely? -
Step C: Revise validation.
Follow #file:workflows/revise.md — Revise the plan to handle missing keys and invalid type formatting (like letters inside floats) by returning 400 Bad Request.
-
Step D: Implement.
Follow #file:workflows/code.md — Implement the
/tasksvalidated POST handler inmain.py. -
Read the code. FastAPI handles data parsing automatically, but manually checking value limits in code reinforces boundary validation.
-
Test the validation using curl:
- Mac/Linux:
# Test Success (201) curl -i -X POST -H "Content-Type: application/json" -d '{"title": "Algorithms", "hours": 2.0}' http://127.0.0.1:8000/tasks # Test Fail (400) curl -i -X POST -H "Content-Type: application/json" -d '{"title": "", "hours": -1.5}' http://127.0.0.1:8000/tasks
- Windows (Command Prompt / PowerShell):
Note: Windows escape syntax for double quotes in JSON requires backslashes.
# Test Success (201) curl -i -X POST -H "Content-Type: application/json" -d "{\"title\": \"Algorithms\", \"hours\": 2.0}" http://127.0.0.1:8000/tasks # Test Fail (400) curl -i -X POST -H "Content-Type: application/json" -d "{\"title\": \"\", \"hours\": -1.5}" http://127.0.0.1:8000/tasks
- Mac/Linux:
-
Review the outputs. Verify that the headers contain
HTTP/1.1 201 Createdfor the valid request andHTTP/1.1 400 Bad Requestfor the invalid request. -
Commit:
git add main.py git commit -m "Module 2: added validated POST /tasks endpoint" git push
Checkpoint
Create checkpoint_02.md:
- Paste the raw header outputs for both the successful and failed requests.
- Why is it bad design to return status code
200 OKwhen an operations request fails due to bad input data? (E.g. returning{"error": "invalid data"}with code 200).