Server-side Programming
Static resources
(html, xml, images, etc)
Dynamic resources
(scripts / programs / processes)
Static v/s Dynamic Resources
Static Resources
fixed representation: delivered to agents exactly as
stored
examples: html, xml, images, etc
no programming required
maintaining large number of static resources can be
cumbersome and difficult
Dynamic Resources
reside in form of scripts / programs / processes
generate client-readable content on the fly
representation may change over time
example: Google Search
Web Server
● Content Management
– Organize resources
– Serve and handle requests
– Path translation / Routing
– Response generation
● Other issues
– Security
– Performance
– Virtual Hosting
– Logging
Server-side Technologies
Zend / Symfony / Cake / Laravel / etc.
PHP
React / Angular
MySQL / MariaDB Django / Flask
Express
Apache Python
Node JS
Linux / Windows / Mac PostgreSQL
Mongo
XAMP Python Django / Flask MEAN / MERN
Servlets / J2EE / Spring / etc. ASP .NET
Java C# / .NET CLR
Oracle / PostgreSQL SQL Server
Tomcat IIS
JVM Windows / Mono
J2EE .NET
[Link]
Run-time environment for Javascript-based
server side programming using V8
Written in C, C++ and Javascript
HTTP module provides a simple in-built web
server
Event-driven, Single threaded, Asynchronous,
Non-blocking I/O
Useful for I/O intensive applications but not for
CPU intensive applications
Hello world Example
[Link]
import { http } from 'http'
[Link](function (request, response) {
[Link](200, {'Content-Type': 'text/plain'});
[Link]('Hello World\n');
[Link]();
}).listen(8888);
Command line
$ node [Link]
Node Architecture and Event Loop
Node Standard Library Javascript
Node Bindings C / C++
(socket, http, etc.)
V8 Thread Event Core
JS Engine Pool Loop modules
Event
Requests Loop
Event Queue
Node Core Modules
● HTTP / HTTPS
● File System (FS)
● Path
● OS
● URL
● Events
File System and Routing
import http from 'http'
import fs from 'fs'
import url from 'url';
import path from 'path';
[Link](function (request, response) {
const basePath = [Link]([Link]([Link]));
let filePath = basePath + [Link];
[Link](filePath,function(err,contents){
if (err) {
[Link](404, {'Content-Type': 'text/html'});
[Link]("404 Not Found");
}
else{
[Link](200, {'Content-Type': 'text/html'});
[Link](contents);
[Link]();
}
});
}).listen(8888);
GET Request Handling
import http from 'http'
import fs from 'fs'
import url from 'url'
import path from 'path'
import * as Engine from './[Link]'
[Link](function (request, response) {
const basePath = [Link]([Link]([Link]));
let u = new [Link]([Link], `[Link]
if([Link] == "/search"){
let query = [Link]('q');
let index = new [Link]();
let resources = [Link](query);
let html = "";
for(let i=0; i < [Link]; i++)
html += resources[i].generateHtml();
[Link](200, {'Content-Type': 'text/html'});
[Link](html);
[Link]();
}
else { /* … */ }
}).listen(8888);
POST / PUT Request Handling
// …
if ( [Link] === 'POST'){
let body = [];
request
.on('data', chunk => {
[Link](chunk);
})
.on('end', () => {
body = [Link](body).toString();
// at this point, `body` has the entire request body stored in it as a string
});
}
// ...
● Using Events, Stream and Buffer
● Requires parsing separately
● Other third-party libraries can be useful
State Management
Client-side
URLs
Form / JS hidden fields
Cookies
Server-side
Sessions
Databases
Caches
Managing state on the client-side
Always send the state information as part of every request.
For example, consider using gmail:
In order to login, type your user-id and password
Server authenticates you and show you your inbox
Server asks the client to store user-id information
Either using URL, Hidden fields, Cookies
Server terminates the connection due to stateless nature
Now, in order to view first unread email you select the email-id and
resend your user-id
This information can be sent either using URL, hidden fields or cookies
Server:
gets your user-id,
locate your inbox based upon user-id
lookup the email in your inbox based upon the email-id
Managing state on the server-side
Server maintains the state – you don't have to send it every
time you make the request. For example, again consider
using gmail:
In order to login, type your user-id and password
Server authenticates you and show you your inbox
Server stores your user-id in the session for a specific time-period
Server terminates the connection due to stateless nature
Now, in order to view first unread email you select the email-id and
resend your user-id
This information can be sent either using URL, hidden fields or cookies
Server:
gets your user-id from session,
locate your inbox based upon user-id
lookup the email in your inbox based upon the email-id
Clears your session once the time-period expires (session timeout)
session-id: 1234
user=farooq
session-id=1234
exchange cookie
Cookies vs Session
Stored on client
Stored on server
More prone to attacks
Safe
Lower Performance
Better performance
Preferred for long-
Preferred for short-
term storage term storage
Easy to scale
Difficult to scale
Express
● Efficient and minimalist server-side framework
● Features
– Routing and request / response handling
– Middleware support for customization
– State management
– Template engine support
$ npm init
$ npm install express
Installation
Basic routing
import express from 'express'
const app = express()
const port = 3000
[Link]('/', (req, res) => {
[Link]('Hello World!')
})
[Link]('/', (req, res) => {
[Link]('Got a POST request')
})
[Link]('/user', (req, res) => {
[Link]('Got a PUT request at /user')
})
[Link](port, () => {
[Link](`Example app listening on port ${port}`)
})
Project Structure
$ npx epress-generator --view=pug my-app
$ npm install
.
├── [Link]
├── bin
│ └── www
├── [Link]
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── [Link]
├── routes
│ ├── [Link]
│ └── [Link]
└── views
├── [Link]
├── [Link]
└── [Link]
7 directories, 9 files
Express Middleware
next() next() ...
request 1 2 n response
middleware
● Functions to extend Express functionality
– Takes three parameters: request, response, next
– Invoked during request-response cycle
– next can invoke next middleware component in chain
● Several built-in middleware components
– Example: static, session, cookies, json, etc.
● Custom components can be developed
– Register appropriate callback using [Link] / [Link] or
[Link] / [Link]
– Call next function at the end
Custom Middleware
[Link](function (req, res, next) {
[Link] = [Link]() // add current time to request
next()
})
[Link](function (req, res, next) {
[Link](req) // log request object
next()
})
Session Middleware
const session = require('express-session'); [Link]('/login', (req, res) => {
const app = express(); // Set session data
[Link](session({ [Link] =
secret: 'your-secret-key', { id: 1, username: 'example' };
resave: true, [Link]('Logged in');
saveUninitialized: true, });
cookie: {
path : ' / ' [Link]('/profile', (req, res) => {
maxAge: 1000 * 60 * 60, // Access session data
httpOnly: true, const user = [Link];
} [Link](`Welcome ${[Link]}`);
})); });
[Link]('/logout',
(req, res) => {
// Destroy session
[Link]((err) => {
if (!err) {
[Link]('Logged out');
}
});
});
Template Engines
● Facilitate rendering HTML using:
– static templates
– dynamically injected properties / objects
● Each engine provides a template language
– static content
– expressions and other high-order features
● Express supported engines
– Jade / Pug
– EJS
– Nunjucks and many others
– Custom engines can be implemented
Pug
[Link] ./views/[Link]
[Link]('views', './views') // default view directory html
[Link]('view engine', 'pug') head
[Link]('/', (req, res) => { title= title
[Link]('index', body
{ title: 'Welcome page', h1= message
message: 'Hello !' } p Welcome to Pug !
) p It generates HTML
})
Express Code Template
[Link]
EJS
[Link] ./views/[Link]
[Link]('views', './views') // default view directory <html>
[Link]('view engine', 'ejs') <head>
[Link]('/', (req, res) => { <title> <%= title %> </title>
[Link]('index', </head>
{ title: 'Welcome page', <body>
message: 'Hello !' } <h1> <%= message %> </h1>
) <p> Welcome to EJS ! </p>
}) <p> It embeds in HTML </p>
</body>
</html>
Express Code Template
[Link]
Nunjucks
[Link] ./views/[Link]
[Link]('views', { autoescape: true, <html>
express: app <head>
}); <title> {{ title }} </title>
</head>
[Link]('/', (req, res) => { <body>
[Link]('[Link]', <h1> {{ message }} </h1>
{ title: 'Welcome page', <p> Welcome to Nunjucks </p>
message: 'Hello !' } <p> It embeds in HTML </p>
) </body>
}) </html>
Express Code Template
[Link]
Database Connectivity
(MongoDB)
$ npm install mongodb // install driver
// ...
const { MongoClient } = require('mongodb');
const str = 'mongodb://localhost:27017';
const client = new MongoClient(str);
async function run() {
try {
// Connect to the MongoDB server
await [Link]();
const collection = [Link]('<db>').collection('<collection>');
result = await [Link]({});
return [Link](result)
} finally {
await [Link]();
}
}
[Link]('/', (req, res) => {
run().then((result) => { [Link](result) });
})
Database Connectivity
(MySQL)
$ npm install mysql // install driver
const mysql = require('mysql')
const connection = [Link]({
host: 'localhost',
user: 'dbuser',
password: 'pass',
database: 'my_db'
})
[Link]()
[Link]('SELECT 1 + 1 AS solution', (err, rows, fields) => {
if (err) throw err
[Link]('The solution is: ', rows[0].solution)
})
[Link]()