Writing basic web/HTTP server using Express.JS framework
Node.JS gives us API to create our own HTTP/web server but these APIs are very raw and low-level which is not suitable for writing large and complex HTTP/web server. Thanks to Express.JS, now it is fun to write a small or a large web application. Express.JS is a Node.JS module, which abstract node's low-level HTTP API and provide us clean and nice interface API.
So if you want to write HTTP server using pure node API, you will require node built-in module called 'http' using var http = require('http')
but if you want to write using express API then you will require node external module called 'express' using var express = require('express')
. Below are some points comparing each others..
Node.JS http | Express.JS |
---|---|
http is Node.Js's inbuilt module |
express is Node.Js's extenal module |
it provides raw and low-level API to create/manage http server | it provides comparativley high level API to create/manage http server |
not suitable for writing large and complex application because its APIs are complex and not very developer friendly | highly recommended for large and complex application because its APIs are simple, clean and manageable. |
less productive: take more time to write small code due to complex API and less abstraction | more productive because its APIs are simple and most basic functions are already implemented internally in express, just reuse it. |
chances of more bug | chances of less bug |
comparatively faster because we are using node's built-in API | comparatively slower because it adds another layer, internally uses Node.JS built-in API |
Installing Express.JS
To use express.js, first, you have to install it in your project folder using npm command. See the cheatsheet or list of command for npm here. Also install body-parser, we will see later why it's required.
npm install express
npm install body-parser
Creating basic server
Basic funda of any server is to serve the response to client request. Depending on the kind of response, we can categorize the server for our understanding.
Static(File) Server: Actual resource requested by client already exist on the server typically as a file, server just have to read and send those file content to the client. So this kind of sever generally serve static content typically (html, css, js, etc) file, they don't have much logic to generate and serve dynamic content. For example, when client request for http://www.example.com/about.html
, server just read the content of 'about.html' file and send it to the client with correct Mime-type(text/html).
Dynamic(API) Server: Actual resource/content requested by the client doesn't exist on the server, server has to generate those content dynamically and send it to the client. So, this kind of server generally generates the content dynamically depending on the client request. For example: when browser request for http://www.example.com/api/add?num1=10&num2=20
, then there is no such file or resources called 'add' instead server will add the number 10 and 20, and send 30 to the client.
Dynamic(API) Server
First, we are creating an express application using const app = express()
then binding it to port 3000
using app.listen(300)
. Express app provide a nice method (get, post, put, & delete) corresponding to HTTP verb. The basic syntax of this method is as below.
express_app.HTTP_METHOD(HTP_URL, CALLBACK_FUNCTION)
e.g app.get('/api/add', handleAddRequest)
This means, whenever client request URL is /api/add
and method is get
then express will automatically call function handleAddRequest
. So our response logic for addition request should be written inside this function.
const express = require("express")
const bodyParser = require("body-parser")
const app = express()
app.listen(3000, () => {
console.log("http server is listening on port 3000")
})
app.get("/", (req, res) => {
res.status(200)
res.send("Hey! you requested me home page? Welcome")
})
app.get("/divide", (req, res) => {
let dividend = req.query.dividend
let divisor = req.query.divisor
try {
let quotient = dividend / divisor
res.status(200).send(JSON.stringify(quotient))
} catch (e) {
res.status(400).send(e.message)
}
})
app.use(bodyParser.json()) // for parsing(req.body) content-type application/json
app.use(bodyParser.urlencoded({ extended: true })) // for parsing(req.body) content-type application/x-www-form-urlencoded
app.post("/add", (req, res) => {
let num1 = req.body.num1
let num2 = req.body.num2
res.status(200).send(JSON.stringify(num1 + num2))
})
In HTTP request there are two way to send data to the server, 1. using URL query if its GET request eg. http://localhost/divide/?dividend=20&divisor=10
, request query data can be accessed in express server using req.query
. 2. using request body if its POST request. Request body data can be accessed in express server using req.body
but before accessing req.body
, we have to use express's body-parser
middleware.
Static(File) server
If you want to create a server that will serve static content from folder 'public' then use the express middleware express.static('public')
by passing desired folder name. Its one line code and we are done.
const express = require('express');
const path = require('path');
const app = express();
app.listen(3000, () => {
console.log('http server is listening on port 3000');
});
app.use(express.static('public'));
// For URL like: /app.js, /style.css etc
[OR]
app.use('/static', express.static('public'));
// For URL like: /static/app.js, /static/style.css etc
[OR]
app.use('/static', express.static(path.join(\_\_dirname, 'public')));
// In above two, static location is relative. If you run express from different folder, it won't work.
// In this, static location is fixed, we can run express server from any folder and it will just work.