6. Chapter review
You started this chapter able to read data from APIs and you're finishing it able to create, update, and delete it. That's the transition from building tools that watch the world to tools that change it, and it's where most real applications live.
What you've accomplished
Through POST, PUT, and DELETE, plus the defensive patterns that make them safe, you've worked through the full CRUD vocabulary that every REST API uses. More importantly, you've learned to apply Chapter 4's Make → Check → Extract pattern to operations that change data, where errors carry higher stakes than simple read failures. The blog-manager example pulled the whole thing together: four methods working through a single class, with consistent error handling, input validation, and status code branching throughout.
Key skills mastered
- HTTP method selection. Pick the correct method for any operation: GET for reading, POST for creating, PUT for replacing, DELETE for removing.
- POST implementation. Send both JSON and form data to create resources. Handle creation-specific status codes (201 Created, 409 Conflict). Validate input before sending.
- PUT mastery. Replace complete resources with new state. Know the complete-replacement contract so you never silently delete fields. Handle concurrent modification (409).
- DELETE safety. Remove resources with confirmation workflows. Treat 404 as success for deletion goals. Handle dependency conflicts (409) and locked resources (423). Never call
.json()on a 204. - Defensive programming for every method. Apply the Make → Check → Extract pattern to data-modifying operations. Validate at all four layers (network, HTTP, format, structure). Give users feedback that tells them what to do.
- Method-specific error handling. Handle each method's unique failure modes: POST validation failures, PUT concurrent modifications, DELETE dependency conflicts.
Habits worth carrying forward
The habits below separate amateur code from professional code. None of them is clever; they're all just discipline:
- Validate before sending. Catch bad input at the boundary to save bandwidth and give immediate feedback.
- Handle method-specific codes. Different methods return different success codes. Check for 200, 201, and 204 as appropriate.
- Treat 404 contextually. For GET and PUT, 404 is an error. For DELETE, it means the goal is already achieved.
- Return structured results. A consistent
(success, data, message)tuple beats scattered raises and silent returns. - Confirm destructive operations. Always wrap DELETE in a workflow the user can back out of.
Checkpoint quiz
If you can answer these without peeking, the material has stuck:
What's the fundamental difference between POST and PUT? When would you use each?
POST creates new resources, the server assigns the ID. PUT replaces an existing resource you specify by ID. Use POST when you don't know the resource's ID yet (it doesn't exist), and PUT when you're updating a specific, existing resource.
Why should DELETE requests treat 404 as success rather than failure?
For DELETE, the goal is "ensure the resource doesn't exist." If you get 404, the resource is already gone, the goal is accomplished. Treating 404 as failure would break idempotent DELETE and confuse users whose second retry finally "succeeds."
What does "idempotent" mean, and which HTTP methods are idempotent?
An operation is idempotent if calling it multiple times with the same data produces the same result as calling it once. GET, PUT, and DELETE are idempotent. POST is not, multiple POSTs create multiple resources.
Why is input validation more important for POST/PUT/DELETE than for GET?
GET only reads, so invalid input is mostly harmless. POST, PUT, and DELETE change server state. Bad input can create junk data, corrupt an existing resource, or delete the wrong thing. Validating at the boundary prevents all of those.
Why might a PUT request return 409 Conflict?
409 for PUT usually means concurrent modification, someone else changed the resource after you retrieved it. Your update would overwrite their changes. APIs detect this with ETags or version numbers; clients handle it by prompting the user to refresh and retry.
Why must you never call .json() on a 204 response?
204 means "No Content", the body is empty. response.json() on an empty body raises JSONDecodeError and crashes your program. Branch on status (200 vs 204) before parsing.
Looking forward
With HTTP methods mastered and defensive handling internalised, you're ready for the next piece of the puzzle: parsing the JSON that these methods return. Chapter 6 dives into the reality of real-world responses, nested structures, inconsistent shapes, missing fields, and the techniques that handle them without brittle code.
The four methods you learned in this chapter, combined with the error handling patterns, are the foundation for every API interaction you'll build from here on. Whether you're working on social media features, e-commerce flows, or content management tools, CRUD is CRUD, and the patterns you've just practised will carry you through the rest of the book.
If you want to cement the pattern in muscle memory before moving on, a short exercise: build a todo list manager using all four methods. POST to create a task, GET to list tasks, PUT to update, DELETE to remove. Run it against httpbin first, then adapt it to any public REST API you're curious about. The more you apply these patterns now, the more natural defensive programming will feel when you meet a real production API.