Node HTTP Module
#
WhyWhat is a Module in Node.js? Consider modules to be the same as JavaScript libraries. A set of functions you want to include in your application.
#
WhatA Module in Node.js is a code package with simple or complex functionality, organized in single or multiple JavaScript files, which can be reused throughout the Node.js application. Each module in Node.js has its own context, so it cannot interfere with other modules or pollute global scope.
Also, each module can be placed in a separate .js
or .mjs
file under a separate folder.
#
Node.js Module TypesNode.js includes three types of modules:
- Core Modules,
- "built-in", meaning they are available anytime you run your file in the Node.js environment
- Local Modules
- Modules you write specific to your program
- Third Party Modules
- Packages from npm
#
Node.js Core ModulesNode.js is a lightweight runtime environment. The core modules include bare minimum functionalities of Node.js. These core modules are compiled into its binary distribution and load automatically when Node.js processes start. However, you need to import the core module first in order to use it in your application.
The list below details some of the important core modules in Node.js.
#
Built-in ModulesHere are a few built-in modules with Node:
fs
allows you to handle the file systemhttp
allows you to initialize Node.js as an hTTP serverhttps
allows you to initialize Node.js as an HTTPS serverpath
allows you to handle file pathsreadline
allows you to handle readable streams one line at the timestream
allows you to handle streaming dataevents
allows you to handle eventsurl
allows you to parse URL stringsquerystring
allows you to handle URL query strings
#
Include ModulesAs we’ve seen before, use the require()
function with the name of the module to import it for use:
Now your application has access to the HTTP module, and is able to create a server:
NOTE: Node.js was created before ES6 import/export syntax. So
const http = require("http")
is used forimport http from "http"
. For exporting, usemodule.exports = { exportedItem }
in place ofexport default exportedItem
. This is called CommonJS, which was the method for using modules before ESM were introduced. To use ESM syntax before we start bundling our server-side code, change the file extension from.js
to.mjs
.
#
The Built-in HTTP ModuleNode.js has a built-in module called HTTP, which allows Node.js to transfer data over the HyperText Transfer Protocol (HTTP).
Note, Node.js modules were created with commonjs (before ES6 import/export syntax), so we’ll have to use the require() method to use our modules.
Here’s a list of common status codes:
Type | Status Codes | Examples |
---|---|---|
Informational | 1xx | 100 Continue, 101 Switching Protocols |
Success | 2xx | 200 OK, 201 Created, 202 Accepted |
Redirection | 3xx | 300 Multiple Choices, 301 Moved Permanently, 302 Found |
Client Error | 4xx | 400 Bad Request, 403 Forbidden, 404 Not Found, 422 Unprocessable Entity |
Server Error | 5xx | 500 Internal Server Error, 503 Service Unavailable |
#
HowSo again, we’ll use the http module with our require method:
#
Node.js as a Web ServerThe HTTP module can create an HTTP server that listens to server ports and gives a response back to the client.
The createServer()
method takes in a callback function that is called once for every HTTP request that's made to the server (hints the reason we call it the request handler). When we call the createServer method, it returns a server object that is an “EventEmitter”.
So, the function passed into the http.createServer()
method will be executed when someone tries to access the server at localhost:3000.
Save the code above in a file called app.js
, and initiate the file:
#
Add an HTTP HeaderIf the response from the HTTP server is supposed to be displayed as text, you should include an HTTP header with the correct content type:
The first argument of the res.writeHead()
method is the status code, 200 means that all is OK, the second argument is an object containing the response headers.
Here are some notable HTTP methods for interacting with the response headers:
getHeaders()
get a copy of the HTTP headers already setsetHeader('header', value)
sets an HTTP header valuegetHeader('header')
gets an HTTP header already setremoveHeader('headername')
removes an HTTP header already set
#
HTTP Request ObjectThe function passed into the http.createServer()
has a req argument that represents the request from the client, as an object (instance of a http.IncomingMessage
). The request object is a ReadableStream, and also an EventEmitter that we can attach event listeners to.
This object has a property called "url" which holds the part of the url that comes after the domain name:
We can also access the http method (GET, POST, PUT, DELETE, etc) with req.method
.
#
HTTP Response ObjectThe second argument that we pass in to the request handler is the res argument. The response object is a WritableStream and an EventEmitter that we can apply event listeners to. Since it is a WriteableStream, we can write a response body out to the client with just a few methods.
Above, we first use the res.writeHead()
to set the headers for our response. The first argument ‘200’ represents the ok status code, and the object with ‘Content-Type’ is our header object describing the response.
You use the res.write()
method to send data to the client in the response body. It will send buffered data to the HTTP response stream.
Lastly, the res.end()
method you’ll always call to close the response. Now our response is complete and sent to the client.
#
RoutesThis is fantastic! But we haven’t covered sending different responses depending on the exact url requested by the client. Let’s do that now with a bit of conditional logic:
Now if the client sends a request to localhost:3000/ they will receive “Home” in a heading 1 tag. If they send a request to localhost:3000/about they will receive “About” in a heading 1 tag.
But what if the user sends a request to a url other than “/” or “/about”? Well we should account for that.
#
POST and PUT RequestsUp until now, we have only been focusing on GET requests to our server. However, accounting for POST or PUT requests are a bit different. For those requests, we want to access the request body to use in our application.
As we mentioned earlier, the request object that's passed in to the request handler callback function is a ReadableStream. We can grab the data right out of the stream by listening to the stream's 'data' and 'end' events.
The stream emits chunks, each chunk being a Buffer.
A Buffer is, “Raw data is stored in instances of the Buffer class. A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized.”
We can collect the data in an array, then at the 'end' event, combine and stringify the result.
Since the request object is an EventEmitter, we can attach an event listener with .on(“event”)
to listen for the “data” events and the “end” event. We use Buffer.concat(chunks).toString()
to decode the Buffer for our use. Once we have the data we need, we can write our response to the client with the appropriate headers. Remember to always call the response objects .end()
method to end the response.
NOTE: “Converting a Buffer into a string ... is referred to as decoding, and converting a string into a Buffer is referred to as encoding.”
#
Error Handling 101Since both the request and response objects are streams and EventEmitters, they will crash the app when an error is thrown. We can account for this by adding an event listener on each for an ‘error’ event. Here we can specify to end the response with appropriate feedback both in the headers and body.
And
#
Takeaways- Modules are packages of code that we can import and export between files in our program
- Node.js comes with core modules such as http, https, fs, path, stream, events, etc
- The Node.js http module enables us to create a server and listen to requests on a specified port
- We can respond to http requests by using methods on the
http.ServerResponse
instance that is passed into our request handler