HTTP
- HTTP
- Node.js
How clients and servers communicate on the web through stateless request and response messages made of methods, paths, headers, and status codes.
What you'll understand
- Why the web is built on a simple request and response exchange
- The parts of an HTTP request and response
- What HTTP methods and status codes communicate
- Why HTTP is stateless and what that means for your server
Explanation
HTTP (HyperText Transfer Protocol) is the language browsers, mobile apps, and servers use to talk over the web. One side, the client, sends a request; the other side, the server, sends back a response. That is the whole model.
A request carries a method (what you want to do), a path (which resource), headers (metadata about the message), and often a body (data you are sending). A response carries a status code (what happened), headers, and usually a body (the data you asked for).
HTTP is stateless: each request stands alone and the server remembers nothing about earlier requests by default. This keeps servers simple and scalable, but it means anything that must persist between requests, like who you are, has to be carried explicitly on each request, usually in a header such as Authorization or a cookie.
Methods describe intent. GET reads, POST creates, PUT and PATCH update, and DELETE removes. Status codes describe the outcome in ranges: 2xx success, 3xx redirection, 4xx the client made a mistake, 5xx the server failed. Reading the method and status together tells you most of what a request did.
Examples
This raw HTTP request asks a server for a user resource:
GET /users/42 HTTP/1.1
Host: api.example.com
Accept: application/jsonA successful response might look like this:
HTTP/1.1 200 OK
Content-Type: application/json
{ "id": 42, "name": "Ada" }This TypeScript example makes the same request from a client using fetch and checks the status before using the body:
const response = await fetch('https://api.example.com/users/42', {
headers: { Accept: 'application/json' },
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const user = await response.json();Common mistakes
- Treating GET as if it can change data. GET should only read; use POST, PUT, PATCH, or DELETE to modify.
- Ignoring the status code and assuming any response is a success. Always check it before using the body.
- Expecting the server to remember previous requests. It does not; send what each request needs.
- Confusing 4xx and 5xx. A 4xx means the client sent something wrong; a 5xx means the server failed.
Best practices
- Choose the method that matches your intent so behavior is predictable.
- Return accurate status codes; they are the fastest signal of what happened.
- Put metadata in headers and data in the body, not the other way around.
- Assume the network can fail and handle non-2xx responses explicitly.
Further reading
- MDN, An overview of HTTP — https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview
- MDN, HTTP response status codes — https://developer.mozilla.org/en-US/docs/Web/HTTP/Status