Course outline · 0% complete

0/29 lessons0%

Course overview →

Designing the Notes API

lesson 9-1 · ~11 min · 27/29

Warm-up: a wrong password on a real account

The answer is 401 with the message "invalid email or password".

401 says the server could not authenticate you, which is the honest description of a wrong password. It is a 4xx because the request was well-formed and simply not accepted, and lesson 3-3's table puts authentication failures exactly there.

The deliberately generic message avoids confirming whether the email exists, which is the enumeration leak from lesson 7-4. Anything more specific, like "wrong password", tells an attacker that the email is a real account and turns a login form into a user-list oracle.

The same string has to come back for both failure modes, which is the part people get wrong. A different message for an unknown email leaks the same information, even though each individual response looks reasonable on its own.

This lesson opens with it because the capstone spec below has to make the same call in real code, alongside the rate limiter that keeps the guessing cheap.

The spec

Time to design a complete service: a personal notes API. Requirements: users sign up, log in, and manage only their own notes.

Applying unit 4's grid, the whole surface is six endpoints:

EndpointPurposeAuth?Success
POST /signupcreate account (hash the password, lesson 7-1)no201
POST /loginverify password, start a session (lesson 7-2)no200
GET /noteslist my notes, paginated (lesson 4-2)yes200
POST /notescreate a note (validated, lesson 5-3)yes201
PUT /notes/:idupdate my noteyes200
DELETE /notes/:iddelete my noteyes204

Failures reuse the lesson 4-3 shape everywhere: 401 unauthorized when not logged in, 403 for someone else's note, 404 for a missing id, 400 invalid_input from validation, 429 from the limiter on /login.

ratelimiterauthsession checkvalidationreject bad inputhandlerbusiness logicresponsestatus + JSONrepositorydata layerevery request walks the same pipeline you built, stage by stage
The full request path of the notes API. Each stage is a lesson from this course, now standing in one line.

Which stage rejects a note that belongs to someone else

The handler, with 403, because ownership is business logic that needs the note loaded first.

Auth only proves who is asking, and this user is logged in, so a 401 would be wrong. The token or session verified correctly, and nothing about that step knows which notes exist.

Validation only inspects the input shape, so a well-formed body for someone else's note passes it without complaint. Validation answers "is this request sensible", not "is this request permitted".

Ownership requires fetching note 17 and comparing its author to the session user, and that is the handler's job because it is the first stage with the note in hand. The answer is 403, which is the same distinction as your lesson 3-3 problem.

QuestionStageFailure
who are youauth middleware401
is the body sensiblevalidation400
does the note existhandler404
is it yourshandler403

The 401 versus 403 line is the one worth memorizing. 401 means the server does not know who you are, and 403 means it knows exactly who you are and the answer is still no.

Which status a successful POST /notes carries

201 Created.

A POST that creates a resource answers 201, typically with the created object in the body so the client does not need a second request to learn its new id. Returning the whole object also lets the client see any server-assigned fields, like a timestamp.

Plain 200 is for reads and updates, and 204 is for successful responses with no body, like DELETE. Each of the three says something different about what happened, which is why picking the right one is free information for the caller.

The REST grid from lesson 4-1 pairs each verb with its success code, and the value is consistency. A client that knows POST means 201 across your whole API can write one code path for creation instead of one per endpoint.

Something new now exists on the server, and plain 200 undersells that. A well-behaved 201 also carries a Location header pointing at the new resource, which is the finishing touch on a create endpoint.