Servers and environment
Route requests by method and URL
Read the incoming method and URL, choose a handler, and return an explicit status and content type for every path.
Every incoming request gives you an HTTP method, a URL, and headers. Your job is to match method and pathname, then send the right status and body.
Parse request.url against a base URL so pathname and query string stay separate:
import { createServer } from 'node:http'
function sendJson(response, status, value, headers = {}) {
response.writeHead(status, {
'content-type': 'application/json; charset=utf-8',
...headers,
})
response.end(JSON.stringify(value))
}
const server = createServer((request, response) => {
const url = new URL(request.url, 'http://localhost')
if (url.pathname === '/notes' && request.method === 'GET') {
return sendJson(response, 200, { notes: [] })
}
if (url.pathname === '/notes') {
return sendJson(
response,
405,
{ error: 'Method not allowed' },
{ allow: 'GET, POST' }
)
}
return sendJson(response, 404, { error: 'Not found' })
})
Match both method and pathname. A query like /notes?limit=10 still has pathname /notes. Read url.searchParams separately and validate every value.
Use status codes that describe what went wrong:
404 Not Found: no route for this pathname405 Method Not Allowed: the pathname exists, but not for this method400 Bad Request: the route exists, but the input is invalid
A 405 response should include an Allow header listing supported methods. Return immediately after you end a response so later code cannot write headers or a second body.
Set Content-Type on success and error responses. JSON should include charset=utf-8. Do not return an HTML stack trace to an API client.
Routing picks a handler. It does not check authorization. A valid match on /notes/42 still needs a permission check before you return that note.
Unexpected handler failures need a final error boundary. Log details on the server and return a generic 500 only if headers have not been sent yet. Once a streamed response has started, closing the response may be the only safe recovery.
Try this on your own project: add POST /notes, validate one query parameter, and send requests that hit 200, 400, 404, and 405. Check each status code, body content type, and Allow header.
Lesson completed