0%

Use node.js to create web server


Use nodejs to create web server

1
2
3
4
5
6
7
8
9
//need to include nodejs core moudul 'http'
const http = require('http');
//and then create a listener to receive incomming message and return response object
const server = http.createServer((req, res) => {
console.log(req);
})
//start a process to keep it running to listen for incomming requests. Event loop will keep running
//first argument accept the port which can listen for the requests, if not, then defult port 80 will be used
server.listen(3000);

Then we can set some respose for request like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const http = require('http');
const server = http.createServer((req, res) => {
console.log(req.url, req.method, req.headers);
//tell that we will response a html type content
res.setHeader('Content-Type', 'text/html');
res.write('<html>');
res.write('<head><title>My page</title></head>');
res.write('<body><h1>Hello world</h1></body>');
res.write('</html>');
//once we end the response, we can't write it anymore
res.end();
})

server.listen(3000);

More about http headerslink

We also can do some judgment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
const url = req.url;
const method = req.method;
if(url === '/'){
res.setHeader('Content-Type', 'text/html');
res.write('<html>');
res.write('<head><title>My page</title></head>');
res.write('<body><form action="/message" method="POST"><input type="text" name="message"></input><button type="submit">send</button></form></body>');
res.write('</html>');
return res.end();
}
if(url === '/message' && method === 'POST'){
fs.writeFileSync('message.txt','DUMMY');
//set statuscode to 302 and then we can redirect to the '/'
res.statusCode = 302;
res.setHeader('Location', '/');
return res.end();
}

//once we end the response, we can't write it anymore
res.end();
})
server.listen(3000);

Streams and Buffers

If we have incomming request, streams here will basically an ongoing process. The request will simply read by node in chunks(in multiple parts) and in the end at some point of time it’s done. Once it’s done we can start interact with the entire request. If you need to works with the single part, then buffers can help us to do that.
That’s adjust the above code for example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if(url === '/message' && method === 'POST'){
const body = [];
//on method allow us to listen certain events
//the data event will be fired whenever a new chunk is ready to be read
req.on('data', (chunk) => {
console.log(chunk);
body.push(chunk);
})
//end event will be fired once it's done parsing the incomming request data or the incomming requests
req.on('end', () => {
const parseBody = Buffer.concat(body).toString();
console.log(parseBody);
})
fs.writeFileSync('message.txt','DUMMY');
//set statuscode to 302 and then we can redirect to the '/'
res.statusCode = 302;
res.setHeader('Location', '/');
return res.end();
}

Input “Hello!” and that’s see the output

1
2
3
4
//the chunks
<Buffer 6d 65 73 73 61 67 65 3d 48 65 6c 6c 6f 25 32 31>
message=Hello%21
//"message" is because I named the input html's name property to "message"

Can use module.exports to split the routes logical code

app.js

1
2
3
4
5
6
7
const http = require('http');

const routes = require('./routes')

const server = http.createServer(routes.handler);
console.log(routes.someText);
server.listen(3000);

routes.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
onst fs = require('fs');

const requestHandler = (req, res) => {
const url = req.url;
const method = req.method;
if (url === '/') {
//some code
}
if (url === '/message' && method === 'POST') {
//some code
return req.on('end', () => {
//some code
});
});
}
//some code
res.end();
};
// module.exports = requestHandler;

// module.exports = {
// handler: requestHandler,
// someText: 'Some hard coded text'
// };

// module.exports.handler = requestHandler;
// module.exports.someText = 'Some text';

exports.handler = requestHandler;
exports.someText = 'Some hard coded text';

Using express.js

It’s will be a lot of work if we write the code by our own, so we can use the third party package to make things simply. The express is the most popular package and it has a lot of benefit for us to choose it.

The request will funneled through a bunch of functions (middleware) by express.js untill we send a response. And this is pluggable nature of express.js, where we can easily add other third party packages.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//const http = require('http');
const express = require('express');//express inculde 'http' for us

const app = express();
//use() is defined by express and allow us to add a middleware function
app.use((req, res, next) => {
console.log('In the middleware!');
next(); // Allows the request to continue to the next middleware in line
});

app.use((req, res, next) => {
console.log('In another middleware!');
//Content-Type is set to html/text by express.js defult
res.send('<h1>Hello from Express!</h1>');
});

//const server = http.createServer(app);
//server.listen(3000);
app.listen(3000);//The same of above two line

We also can use
app.post()
app.get()
to execute certain code only if the post request or get request(same of the patch, put, delete).
Otherwise they work just like app.use().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const express = require('express');
const bodyParser = require('body-parser');//need to install body-parser

const app = express();
//can help us parse the request data like we use Buffer without express
//in the bodyParser.urlencoded() function, it already call next() for us
app.use(bodyParser.urlencoded({extended: false}));
//must above the "app.use('/',...) block", or it will be never execute. Unless we set app.use('/') to app.get('/').
app.use('/add-product', (req, res, next) => {
res.send('<form action="/product" method="POST"><input type="text" name="title"><button type="submit">Add Product</button></form>');
});

app.post('/product', (req, res, next) => {
console.log(req.body);
res.redirect('/');//it do all the job for us so we don't need to set status code or set header anymore
});

//if we set app.use() to app.get() or app.post(), it will do exactly when the path is matched.
app.use('/', (req, res, next) => {
res.send('<h1>Hello from Express!</h1>');
});

app.listen(3000);