[Node.js] Creating Webserver (p1)
I. Client and server
- Clients and servers communicate by exchanging messages request and response.
- Each computer is identified by IP address
- To communicate, server/client needs to connect to IP address of each other to open the socket between 2 computers.
II. Create a server using http module
1. http module
- http is a built-in module of Node.js, used to create HTTP server which listens to server ports and give a response to the client.
- http stands for Hyper Text Transfer Protocol.
// require http module
const http = require('http');
// create HTTP server using createServer()
// whenever user sends a request to the server, callback fnc will be fired.
http.createServer((req, res) => {
// send a response to client
res.write("Welcome!");
// end the response
res.end();
}).listen(3000); // server is listening on port 3000
// or http.listen(3000);
- http.listen(port, hostname - IP address, backlog - max length of pending connections' queue, cbFnc - fired when listener has been added): makes server listen to a specific port on computer.
- http.get(): sets method to GET, returns an object containing user's request.
- http.request(): returns an object containing user's request.
2. HTTP header
- HTTP header allows client and server pass additional information with an HTTP request or response.
- Request headers contain infomation about the resource to be fetched.
- Response headers provide information about response's location or the server itself.
- Representation headers is information about the body of the resource.
- Payload headers is information about payload data such as content length, transport's encoding.
// writeHead(statusCode - number,[statusMsg - string],[headers - object]
// a response header sending text
res.writeHead(200, {'Content-Type': 'text/plain'});
// a response header sending html
res.writeHead(200, {'Content-Type': 'text/html'});
III. Serve data to client
1. Buffers and streams: consuming data before it all arrived
- Buffers is a temporary storage that a stream takes to hold data until it is consumed.
- Streams transfer data with a better performance.
- There are 4 types of streams:
Readable streams to read data from a stream.
const fs = require('fs');
// create read stream, read file and return chunck of data little by little
let myReadStream = fs.createReadStream('filename', 'utf8');
// createReadStream inherits EventEmitter so it can listen to events -> cbFnc is executed when a chunk arrives
myReadStream.on('data', (chunck/buffer) => {
// do smt with a chunk of data
});
Writable streams to write data to a stream.
let myWriteStream = fs.createWriteStream('filename');
myWriteStream.write('data');
Duplex can read and write to a stream.
Transform streams can read and write to a stream but data can be modified while reading/writing.
2. Pipes
- Takes data from read stream then pipes them to write stream
const fs = require('fs');
// Step 1: Create read stream
let myReadStream = fs.createReadStream('original.txt','utf8');
// Step 2: Create write stream
let myWriteStream = fs.createWriteStream('copy.txt');
// Step 3. Use pipe()
myReadStream.pipe(myWriteStream);
3. Serve HTML page
http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/html'})
let myReadStream = fs.createReadStream("index.html", 'utf8');
// res object is a writable stream
myReadStream.pipe(res);
// or
fs.createReadStream("index.html", 'utf8').pipe(res);
});
4. Serve JSON data
const person = { "name": "Vivian", "gender": "female"};
http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'application/json'})
let data = JSON.stringify(person);
res.end(data); // arg should be string or buffer
});
IV. Express JS
- An easy and flexible routing system.
- Integrating with many templating engines to build dynamic content.
- Containing middle ware framework
- Installation:
npm install express --save
// return a function
let express = require('express');
let app = express();
// app.get(route, cbFnc) instructs what to do when a get request to the / route is called
app.get('/', (req,res) => {
// send input to the client
res.send("Hello world!");
});
app.listen(3000);
- app.set(name,value): assigns the setting name to value, configure the behavior of the server.
- res.send(data - string or buffer or object) : sends the HTTP response
- res.sendFile(path, [options], [cbFnc]): transfers the given file and sets Content-Type value based on the given file extention.
- res.render(view,[{}],[cbFnc]): render a view (template for dynamic content) and sends rendered HTML string to client. {} contains embedded data to be passed to view (.ejs).
1. HTTP methods - kinds of request client make
- GET
- POST
- DELETE
- PUT
2. Route paramters - dynamic request
// param can be named anything
app.get('/profile/:paramName', (req,res) => {
// param is accessed through req object
req.params.paramName;
});
3. Query strings
- Additional data added to a HTTP request in form of name-value pair
- Separated by & if there are many query strings:
?person=vivi&dept=it
- Access query string:
req.query
-> return an object{dept: 'it', person: 'vivi'}
V. Templating (EJS)
- Used to embedded dynamic data to HTML.
- Installation:
npm install ejs --save
1. Templating syntax
- Output data:
<%= %>
- Output JS code:
<% %>
- Looping
<% data.arrayName.forEach((item) => {%>
<li><%=item%></li>
<%});%>
All rights reserved