The Quest Example
This example is a bit more elaborate and uses some add-on modules, installed using NPM. Then we'll see some callback-based I/O.
The Express Module¶
A popular module for routing and many other things is called Express. Here is some information on routing. To install it, see installing. I won't go over that.
Express Example¶
Here's the code for the express example. As you can see, the single responder callback has been broken up into a collection of handlers for particular routes that are matched against the URL, just like in Flask.
One important difference is that in Flask, both methods are combined
in a single handler (and we distinguish them by looking at
request.method
), but here we differentiate by saying app.get()
; we
would say app.post()
to support a POST method.
var myPort = 1942;
var express = require('express');
var app = express();
// respond with "hello world" when a GET request is made to the homepage
app.get('/', function (req, res) {
res.send('hello world');
});
app.get('/hello/', function (req, res) {
res.send('Hello to you, too!');
});
app.get('/bye/', function (req, res) {
res.send('Come back soon!');
});
function collatzNext(n) {
return ( n % 2 === 0 )? n / 2 : 3 * n + 1;
}
app.get('/collatz/:start', (req, res) => {
// a simple computation
var num = req.params.start;
var next = collatzNext(num);
// var resp = 'num is '+num+' and next is '+next;
var resp = 'num is '+num+' and next is <a href="/collatz/'+next+'">'+next+'</a>';
console.log(resp);
res.send(resp);
});
app.listen(myPort, () => console.log(`Example app listening on port http://0.0.0.0:${myPort}!`));
Notice the parameterized URL, this time using colons instead of angle
brackets: /collatz/:start
rather than /collatz/<start>
.
So, given your knowledge of Flask, the learning curve for Node and Express is much less steep.
QuestForm Example¶
Our last example has two routes, both matching /
- GET reads an HTML file from disk. That HTML file contains a form to
fill out. The form posts to the
/
route. - POST gets the form data that was submitted, and writes (appends) it to a log file of the form submissions.
Both reading the HTMl file from disk and appending to the log demonstrate the callback-style coding.
Here's the code:
var myPort = 1942;
var express = require('express');
var fs = require('fs');
var bodyParser = require('body-parser');
var app = express();
// set up static file serving, served out of the 'static' folder:
// we'll use this for CSS and our logo
app.use(express.static('static'))
// for parsing application/xwww-
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', function (req, res) {
// A templating system would probably be better, and it is
// inefficient to read the file every time, but what the heck
fs.readFile('questform.html', function (err, data) {
if(err) {
return console.error(err);
}
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
res.end();
});
});
// The questform will submit to the empty string,
// which is the same route, but using POST
app.post('/', function (req, res) {
console.log('body')
// the bodyParse creates this, as JS object with the form data
console.log(req.body);
fs.appendFile('questform.log',
// JSON is easy to parse
JSON.stringify(req.body)+'\n',
function (err, data) {
if(err) {
console.log('error writing to questdata.log: '+err);
}
});
// happens concurrently with writing the log
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('Thanks for your submission');
res.end();
});
const msg = `Example app listening on port http://0.0.0.0:${myPort}!`;
app.listen(myPort, () => console.log(msg));