Writing basic web/HTTP server using Express.JS framework

backend5 Min to Read13 Aug 17

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.

Reference

If you loved this post, Please share it on social media.