Project: rebuild Week 2's notes API in FastAPI#
No walkthrough here, on purpose, the same reasoning as ../../project/README.md before it. You've read the four notes in ../notes/. This is where you find out if that was actually enough to rebuild something you've already built once, by hand, in Flask.
What you're rebuilding#
Read Week 2's notes API again if it's been a while, Flask hasn't come up since Week 3, that's a long gap. The finished version is solutions/notes_api.py. Same shape, same endpoints, same data, rebuilt with FastAPI doing the validation instead of you:
- GET /notes, list every note.
- GET /notes/{note_id}, get one specific note. A real 404 if the id doesn't exist, same as before.
- POST /notes, create a note. This time, the request body is a pydantic model, not
request.get_json()plus a.get("text")that silently accepts a missing field. - PUT /notes/{note_id}, update an existing note's text. Also a 404 if the id doesn't exist.
- DELETE /notes/{note_id}, delete a note. Also a 404 if the id doesn't exist.
Each note is still {"id": 1, "text": "Buy milk"}, and notes still persist to a JSON file on disk, so a restart doesn't lose them. load_notes() and save_notes(notes) don't need to change at all: they're plain Python functions that read and write a file, nothing about switching web frameworks touches them.
Goal#
The same working API as Week 2, endpoint for endpoint, minus every hand-written shape check. A request missing "text", or sending a number where "text" should be a string, should never reach your route function at all; FastAPI's automatic validation is what catches that now, not an if statement you write.
Constraints#
- Use a pydantic model as the request body's type for POST and PUT, the actual point of this rebuild. Compare what you no longer have to write against
solutions/notes_api.py'screate_note. - "No note with this id" is not a validation problem; it's your own lookup, the same job
find_notedid in Week 2. FastAPI can't know an id doesn't exist just from a type hint, so that 404 is still logic you write, usingfastapi.HTTPExceptioninstead of Flask'sreturn jsonify(...), 404. Read FastAPI's own documentation forHTTPException, cold, the same way you read pydantic's docs cold for the previous project; there's no note in this sub-step covering it, on purpose. - Persistence still needs to work: restart the server and your notes should still be there.
- Anything not specified here (file layout, variable names, whether
NoteInandNoteOutare the same model or two separate ones) is your call to make and justify, not a gap to ask about.
Try it without curl#
Once it's running (fastapi dev app.py, or whatever you named your file), open http://127.0.0.1:8000/docs instead of reaching for curl first. Every endpoint you've built is already listed there, with its expected request shape and a button to send a real request. Confirm a well-formed request works, and that a broken one (a missing field, a wrong type) comes back as a 422 you never wrote a line of code for.
When you're done#
Compare against your own Week 2 app.py (or solutions/notes_api.py) side by side. Every place that used to be a manual check, missing-field handling in create_note, the find_note-then-None-check pattern repeated three times, should be either gone (handled by a type hint) or smaller (just the 404 lookup itself, nothing about shape). If a check you used to write by hand is still there in exactly the same form, that's worth a second look: either it's genuinely still your job (a 404 lookup is), or it's something FastAPI was supposed to take over.