Node.js Backend Development - Working with Responses
In the previous article we learned how to create our own custom Node.js modules and how to use them. The complete code for the previous article can be found on the Github repository Learn Node.js With Sabuj. You will also find all the code in the same repository. Browse to the specific branch 004_http_server_response for finding all the codes specific to this article.
Create or choose a directory where you want to keep JavaScript files. You can also clone the Github repository, but it is highly advised that you do not just copy and paste, instead write all code by your own hand.
How to Get Response Objects
We do not create response objects, instead Node.js provides us with the response object when a new request comes to our web server application from a web browser or other user agents. Response objects are not reused, instead a new request object is created every time. Request objects are passed through the callback function and passed to the createServer() function as the second parameter.
What we are calling the response object is actually an object of the class ServerResponse from the http module. This class is full of useful methods that we will learn below.
writeHead()
We are already familiar with writeHead(). It has two responsibilities, one is to send the status code and the other is to send the headers. We did not talk about the third one, status message; to keep things simple I did not talk about the third one in the beginning. So, it accepts three parameters: the first one is the status code, the second one is the status message, and the third one is the headers object. The first parameter is mandatory and the later two are optional.
The first parameter is a three digit integer for an HTTP response code. For example, 200 is a response code to tell user agents that everything is alright, 404 is a response code to tell the user agent that the resource requested was not found.
Machines or user agents prefer numbers to know about the status of the request made. But we also need to provide some human readable text so that we can tell end users or programmers who are debugging the application about what happened. This is where the status message comes into play. We all often see messages like these: "404 - Not Found", "500 - Internal Server Error" when browsing websites. The first three digit number is for the user agents to understand what happened and the text message is for the humans. You are at your own liberty to write whatever you like for the message part, but it is advised that you use commonly used phrases for corresponding status codes.
Note: If you provide a string as the second parameter, it will be considered as the human readable status message against the status code, and if it is an object then then it will be considered as the headers.
As noted before, headers can be passed as the second or the third parameter. When a status message is passed as the second parameter, headers will be passed as the third parameter as an object.
Headers are key value pairs that must comply with HTTP standards. You can find a set of standard headers in the RFC documentation on HTTP.
Let's modify the code from the previous article to use status messages.
responder.js
var fs = require('fs');
exports.serveRequests = function(request, response){
fs.readFile('html/home.html', function (error, file_data){
if (error){
response.writeHead(500, "Internal Server Error",
{
'Content-Type': 'text/html'
}
);
response.end("<b>Something Went Terribly Wrong</b>");
}else{
response.writeHead(200, "All is well",
{
'Content-Type': 'text/html'
}
);
response.end(file_data);
}
});
};
write()
We did not use this function before. Instead of using this we used the end() method. What write() does is it sends data to the user agent. As the first parameter, you can pass a string or a buffer. If you pass a string then you should pass the encoding of the string through the second parameter.
Remember that when write() is called the first time, it sends a status with the status message and headers, and then sends the data you passed to it. Consecutive calls only send the data passed to it.
end()
We are already familiar with this method. This method is used to end the request initiated by the user agent. Optionally we can send some data with it. If you want to send data with it, you can pass string or a data buffer as the first parameter and an encoding as the second parameter. The second parameter is not needed when we are using data buffer instead of string.
So, basically end() with some data is equivalent to calling write() with data and end() with nothing.
Let's rewrite our code to use both write() and end():
var fs = require('fs');
exports.serveRequests = function(request, response){
fs.readFile('html/home.html', function (error, file_data){
if (error){
response.writeHead(500, "Internal Server Error",
{
'Content-Type': 'text/html'
}
);
response.write("<b>Something Went Terribly Wrong</b>", "utf8");
response.end();
}else{
response.writeHead(200, "All is well",
{
'Content-Type': 'text/html'
}
);
response.write(file_data, "utf8");
response.end();
}
});
};
finished
This attribute of the response object indicated whether the request is finished or not. It is just a boolean attribute.
getHeader()
I told you before that headers are just key value pairs. So, if you want to get a value of a header that you already have set or any other part of the application has set, then you can retrieve it using getHeader(key) by passing the key with the method.
getHeaderNames()
This method is used to get all the header names as an array of strings.
getHeaders()
This method returns the headers object. So, it will be very helpful to access the headers from a part of the application that is not setting the headers, or the headers are not directly available to it.
hasHeader()
It is used to check by passing a header key to check whether the header exists.
headersSent
This is a boolean attribute that will help you check whether the headers are already sent or not.
removeHeader()
Sometimes we may need to remove a header with its key form the response. Use this method to carry out the job.
setHeader()
writeHead() is not the only way to set headers. You can set headers anytime before sending any data to the client with write() or end(). Use setHeader(key, value) format to set header.
Conclusion
There are a lot of things that you can customize in your simple HTTP server. Try using the methods and attributes above to test them yourself. Keep practicing with Node.js and keep an eye on this blog for new posts.
About the Author
My name is Md. Sabuj Sarker. I am a Software Engineer, Trainer and Writer. I have over 10 years of experience in software development, web design and development, training, writing and some other cool stuff including few years of experience in mobile application development. I am also an open source contributor. Visit my github repository with username SabujXi.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment