What's the purpose of setting http headers and setting appropriate status codes?

I understand headers are used to convey additional information between client and a server. I recently developed a small web-app in node for learning and have not updated any response status codes in headers manually.

For any get request I simply send back the appropriate response file which could be an ejs or html file, without bothering to update the headers. Well the app works just fine but now I see lot of other codes where the headers are updated before sending the response.

For e.g, res.writeHead(200, {'Content-Type': 'text/html'});

Whom does it help? Is it for debugging ? What's the big picture I am missing?


Let's start with an example of an http response borrowed from MDN:

HTTP/1.1 200 OK
Date: Sat, 09 Oct 2010 14:28:02 GMT
Server: Apache
Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT
ETag: "51142bc1-7449-479b075b2891b"
Accept-Ranges: bytes
Content-Length: 29769
Content-Type: text/html

<!DOCTYPE html... (here come the 29769 bytes of the requested web page)

In this HTTP response, there are three parts to it. The first line gives you the protocol and the status. The next block of lines (up until an empty line) are the headers. Then, follows the (optional) content itself.

The status is a required part of an http response as it's sent with every response and informs the recipient whether this is a normal response with content (200) or a redirect (3xx) or an error (4xx or 5xx). Within nodejs, the status will generally default to 200 so if you don't set it, it will automatically be set to 200.

Http headers are used by the recipient for various things. What they are used for depend upon which header you're talking about. Here are a few examples:

Content-Type - Tells the recipient what type of content is in the body of the response. If they don't know the type of the content, then they have to guess and try to figure it out and that's far, far, far less desirable than telling them whether the content is meant to be text/plain or application/json or text/html or image/jpeg, etc...

Content-Length - Tells the recipient how long the content is in bytes. This is required when the content's format does not, by itself, tell the recipient where the end of the response is.

Transfer-Encoding - Tells the recipient how the body of the response is encoded for transfer (for example gzip).

Cache-Control - Gives the recipient information about how long this response can be cached.

Set-Cookie - Sends the recipient a cookie for the client to save and send back with future requests to this origin.

Location - A URI that goes with a 3xx status to indicate where the client should redirect to.

These were just a few examples. There are probably thousands of possible headers, each with their own purpose.

Whom does it help?

It's used by the code that is receiving the http response to know how to interpret it.

Is it for debugging?

That's not its main purpose, but when deubgging a problem, you may look at the detailed headers to see if they are what you expect them to be. For example, if req.body is empty in Express when you're expecting it to be populated, you would look at the content-type to see if it's what you were expecting and matches something you have middleware installed for to read and parse and put into req.body because if the content-type isn't something you expected, then your code that receives this response wouldn't be configured properly to handle it.

What's the big picture I am missing?

Headers are meta data that describes what's in the response and gives the recipient information that is often necessary for knowing how to read the response properly.