Skip to content

Step 1 of 5 · Reading · ~3 min

Read

Routing & Responses

Static Path Routing

A parsed request has a method and a target. Your server has handlers. Routing is the map between them, and with exact paths only (patterns come next lesson) you can concentrate on what makes a router different from a dictionary: what it says when nothing matches, and how it cleans the target before looking anything up.

The route table

GET   /           -> index
GET   /about      -> about
POST  /api/users  -> create_user
GET   /api/users  -> list_users

The key is the pair (method, path). GET /api/users and POST /api/users are different routes with different handlers, which is how REST says "same resource, different verb". A map keyed on the path alone cannot hold both.

Three kinds of "no match"

  1. Unknown path: nothing is registered under any method. 404 Not Found.
  2. Known path, wrong method: DELETE /api/users when only GET and POST exist. The lazy answer is 404. The correct answer is 405 Method Not Allowed plus an Allow header listing what would work. 404 says "nothing here", 405 says "something is here, you used the wrong verb". To tell them apart you must index by path first and by method inside it, which is also what lets you build the Allow list.
  3. HEAD: a path with a GET handler must also answer HEAD (same status and headers, no body, as in the response lesson). A router does this for you unless a HEAD handler was registered explicitly. HEAD therefore appears in the Allow list whenever GET does.

Clean the target before lookup

The request target is not a path yet. Apply these steps in this order:

  1. Cut the query string at the first ?. /about?ref=footer routes as /about.
  2. Percent-decode once. %61 is a, so /ab%6Fut is /about. A % that is not followed by two hex digits is malformed, and so is a decoded NUL (%00): 400 Bad Request. Decode exactly once: /%2561bout becomes /%61bout, not /about. Decoding twice is how a request that passed your checks turns into a different request after them.
  3. Trailing slash. This course treats /about/ and /about as the same route: if the path is longer than one character and ends with /, drop that one slash. The root / is left alone.
  4. Match case-sensitively. /About is not /about.

Registration time

Registering the same (method, path) twice is a programming error, and real routers fail fast at startup rather than let the second handler silently shadow the first. This course keeps the first registration and reports duplicate <METHOD> <path> for the second.

Worked trace

With the table above plus HEAD /health -> health_head:

Request lineCleaned pathResult
GET /about?ref=footer HTTP/1.1/about200 about
HEAD /about HTTP/1.1/about200 about (GET fallback)
DELETE /api/users HTTP/1.1/api/users405 Allow: GET, HEAD, POST
GET /api%2Fusers HTTP/1.1/api/users200 list_users
GET /About HTTP/1.1/About404
GET /a%zz HTTP/1.1none400

Common mistakes

  • Answering 404 for a wrong method, so clients never learn what is allowed.
  • Matching before cleaning, so /about?x=1 and /ab%6Fut are 404s.
  • Decoding twice, which makes /%2561bout reach /about.
  • Listing Allow in registration order. Sort the methods alphabetically so the answer does not depend on file order.
  • Forgetting that HEAD belongs in the Allow list.

Your exercise

The input is a route table, an empty line, and request lines as they arrive from the previous stage. The starter reads both and gives you a path-first table. You clean each target and decide between 200, 404, 405 and 400.

Up nextPath Parameters & Query StringsRouting & Responses

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…