HTTP Headers
This guide provides a quick overview of HTTP headers and lays the groundwork for a thorough understanding of the topic.
Background
HTTP requests consist of the following: a request line, a list of headers, and an optional body. Example request:
GET /photos/cat.png HTTP/1.1
Content-Type: image/png
Similarly, HTTP responses consist of the following: a status line, a list of headers, and an optional body. Example response:
HTTP/1.1 200 OK
Content-Type: image/png
...
Web libraries and frameworks manage many of these details for you when handling requests such as this. In Express, for example, the res.sendFile method could be used in the above case without explicitly stating the Content-Type or even the response status. Still, it’s good practice to understand how requests and responses are constructed and handled by both the server and the browser. With that in mind, this article explores the second component of both requests and responses: headers.
What are headers?
HTTP headers are parameters included in the header section of a request or response which act as operational constraints. In other words, they carry additional information to let the receiver know how to handle the transaction. RFC 7231 reads, “These fields act as request modifiers, similar to the parameters on a programming language method invocation.”
Headers are separated into two categories: request headers and response headers, though some pertain to both requests and responses, known as general headers. For example, the Content-Type header listed below is used by both.
How should I use headers?
You should use headers to include any relevant information regarding your transaction. At a minimum, your responses should contain enough information for clients to understand how your API can be used.
Consider RESTful API design. Cacheability is one one of the core principles of the REST architecture, so your response should indicate whether the response body is cacheable or not. This is done via headers — in this case, the Cache-Control header.
As mentioned above, web libraries and frameworks abstract much of the HTTP protocol for developers. It is good practice to weigh the pros and cons of this abstraction — it can allow for less verbose code, more digestible pull requests, and a generally more readable, maintainable codebase. If used without caution, however, these abstractions can lead to obfuscation of the underlying architecture of your API and actually hurt its readability. In this case, explicit use of headers is recommended. A good rule of thumb is to follow the examples and style guidelines, if provided, by your library or framework of choice.
Common headers
Below are some common request and response headers you’ve likely seen before. For more information on these and other headers, see the Further Reading section at the bottom.
Request headers
Accept: Acceptable media type(s) in the response body
EXAMPLE: Accept: text/htmlAuthorization: The authorization scheme and any associated tokens for authorizing a user agent
EXAMPLE: Authorization: Basic abcd1234Content-Type: The media type of the request body
EXAMPLE: Content-Type: application/jsonCookie: Contains cookies previously sent from the server or set in JavaScript via Document.cookie
EXAMPLE: Cookie: sessionToken=abcd1234; HttpOnly
Response headers
Cache-Control: Indicates the cacheing mechanism that should be followed by the client
EXAMPLE: Cache-Control: max-age=86400Content-Type: The media type of the response body
EXAMPLE: Content-Type: text/htmlSet-Cookie: Sends a cookie to the client
EXAMPLE: Set-Cookie: sessionToken=abcd1234
Further reading
MDN: lists most HTTP headers with details on how to use them — a good first stop when in need of a reference
RFC 7231: the RFC which specifies many HTTP headers (see sections 5 and 7 for request headers and response headers, respectively)