Webserver Programming II
Info 253A: Frontend Web Architecture
Kay Ashaolu
What have we done
- We have created a server that can accept HTTP requests, and send HTTP responses back
- We have full control over what we send back as a response
- We are using JavaScript in order to fully control the back-end
More about routes
- Routes connect URL paths to callback functions
- You are essentially creating an "event listener"
- On the event that a client goes to the "/" path
- Execute the assigned callback function
Quick note
- A server application is continuously running
- It does this so that it always listens to requests
- In order to exit a NodeJS application you must kill the application
- This is done in Unix by the keyboard combination
Control + C
Route Example
app.js
var express = require('express'); // Adding the express library
var app = express(); // Initializing application
app.get('/', function (req, res) {
res.send("<html><head><title>Homepage</title></head>\
<body><h1>This is the home page!</h1></body></html>");
});
app.get('/about', function(req,res) {
res.send("<html><head><title>About</title></head>\
<body><h1>This is the about us page!</h1></body></html>")
});
app.get('/blog/post-1', function(req,res) {
res.send("<html><head><title>Blog 1</title></head>\
<body><h1>This is the first blog post</h1></body></html>")
});
var server = app.listen(3000, function () {
console.log('Server on localhost listening on port 3000');
});
What's happening
- We have explicitly told our server to respond to three GET requests in a specific way
- We use res.send() to send the raw text that we want our client (the browser) to receive
- Note that we are sending pure html text to the client. The browser then creates a DOM from that text and displays the web page
What about our static files?
- Remember our apache server last week, that served CSS and JS files
- We would need something like that in order to host our own CSS and JS files
- Otherwise we would need to write our CSS in the app.js file itself
Express and static files
- Express has a mechanism to set a directory to be treated as a static server
- When a user goes to a particular path, the file that is there is sent to the client as is
- Advantage: no code needs to be executed: just send data from the file to client
- Advantage: this can be cached: only if the file changes does this route's cache needs to be udpated
- This is different with the routes that we have been using so far
Static example
app.js
var express = require('express'); // Adding the express library
var app = express(); // Initializing application
// Set the path "/static" to serve files from the static folder
app.use('/static', express.static(__dirname + '/static'));
// Define your routes here
app.get('/', function (req, res) {
res.send("<html><head><title>Homepage</title>\
<link rel='stylesheet' href='/static/css/style.css' /></head>\
<body><h1>This is the home page!</h1>\
<script type='text/javascript' src='/static/js/script.js'></script></body></html>");
});
// Start up server on port 3000 on host localhost
var server = app.listen(3000, function () {
console.log('Server on localhost listening on port 3000');
});
Static example
static/css/style.css
h1 {
color: blue;
}
Static example
static/js/script.js
alert("script.js has been loaded!");
What's happening here?
- We have set the path '/static' to run as a static server
- Any path that starts with '/static' will serve files "as is" from the "static" folder
- Check it out by going to http://localhost:3000/static/css/style.css
What's happening here?
- Because of our static server, we can serve our own static files
- Look at the HTML being sent from the '/' route
- The HTML code includes a link to a style sheet and an include to a JavaScript file
- This is why the heading was blue and the alert box appeared
This is great, but...
- Writing out all of that text within a callback gets annoying quickly
- What if you want to have HTML code common to several pages on your website?
Templates and template engines
- There are a myriad of template engines out there
- The idea is to write the HTML code that does not change in a "template"
- And then designate placeholders for parts of the web page that does not stay the same
- This is how dynamic pages are created (more on this next week)
Template Example
- First we need to install a module that will add this functionality for us
- Let's add mustache-express, which is a module that integrates express with the mustache template engine
- We do this by going to the terminal and within the root directory of our project and executing the command:
npm install mustache-express --save
Template Example
app.js
var express = require('express'); // Adding the express library
var mustacheExpress = require('mustache-express'); // Adding mustache template system
var app = express(); // initializing application
var template_engine = mustacheExpress(); // initializing template engine
// set the path "/static" to serve files from the static folder
app.use('/static', express.static(__dirname + '/static'));
// Set templating engine and location of templates
app.engine('html', template_engine); // set html parsing to the template engine
app.set('views', __dirname + '/views');
// Define your routes here
app.get('/', function (req, res) {
res.render('index.html');
});
// Start up server on port 3000 on host localhost
var server = app.listen(3000, function () {
console.log('Server on localhost listening on port 3000');
});
Template Example
views/index.html
<html>
<head>
<title>Homepage</title>
<link rel='stylesheet' href='/static/css/style.css' />
</head>
<body>
<h1>This is the home page!</h1>
<script type='text/javascript' src='/static/js/script.js'></script>
</body>
</html>
What's happening?
- This code does the same thing as the previous example
- However, we loaded the html template "index.html" in the views folder
- We set the 'views' folder as the location of all templates
- We set 'html' as an extension of the rendering engine set by the mustache express module
- That's why when we use "res.render('index.html'), NodeJS knows to go to the views folder and use the mustache-express template rendering engine to render index.html
But why use template engines at all?
- We ran "index.html" through a template engine
- But all we did is print the contents of "views/index.html" to the screen
- Couldn't we do this with static pages?
- Why use a template rendering engine at all?
Dynamic Pages
- We want to create pages that are different dependent on many different factors:
- Authentication
- Authorization
- Data embedded in the URI
- Data submitted in a form
- Location
- And so on
- More on this next week, but here's a sneak peak
Grand Example
app.js (1/3)
var express = require('express'); // Adding the express library
var mustacheExpress = require('mustache-express'); // Adding mustache template system
var app = express(); // initializing application
var template_engine = mustacheExpress(); // initializing template engine
// set the path "/static" to serve files from the static folder
app.use('/static', express.static(__dirname + '/static'));
// Set template engine and location of templates
app.engine('html', template_engine); // set html parsing to the template engine
app.set('views', __dirname + '/views');
Grand Example
app.js (2/3)
// An object that contains a quote that we want to display for a day of the week
var quote_db = {
'sunday': "Life is about making an impact, not making an income. \
–Kevin Kruse",
'monday': "Whatever the mind of man can conceive and believe, it can achieve. \
–Napoleon Hill",
'tuesday': "Strive not to be a success, but rather to be of value. \
–Albert Einstein",
'wednesday': "You miss 100% of the shots you don’t take. \
–Wayne Gretzky",
'thursday': "Every strike brings me closer to the next home run. \
–Babe Ruth",
'friday': "We become what we think about. \
–Earl Nightingale",
'saturday': "Life is what happens to you while you’re busy making other plans. \
–John Lennon",
}
Grand Example
app.js (3/3)
// Define your routes here
app.get('/', function (req, res) {
day = req.query.day_of_week;
console.log("Received request for quote for day " + day);
res.render('index.html', { 'day': day, 'quote': quote_db[day] } );
});
// Start up server on port 3000 on host localhost
var server = app.listen(3000, function () {
console.log('Server on localhost listening on port 3000');
});
Grand Example
views/index.html
<html>
<head>
<title>Homepage</title>
<link rel='stylesheet' href='/static/css/style.css' />
</head>
<body>
<h1>This is the home page!</h1>
<p>The quote for {{day}} is: {{quote}}</p>
<br />
<form action="/" method="GET">
<label for="day_select">Select a day</label>
<select name="day_of_week" id="day_select">
<option value="sunday">Sunday</option>
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
</select>
<input type="submit" value="Give me a quote" />
</form>
</body>
</html>
What's happening
- First we created a form that is going to send an GET request to the "/" route
- It will pass a parameter called "day_of_week"
- The server will gain access to that parameter using the req.query object
What's happening
- The server then accesses its "quote_db" to retrieve a quote for that particular day of the week
- It then passes the day and the quote to the template engine
- The template "index.html" replaces the tags {{day}} and {{quote}} with the values specified in the object passed by the function call res.render()
- And we see it on the screen
Questions?
Webserver Programming II - Frontend Webarch
By kayashaolu
Webserver Programming II - Frontend Webarch
Course Website: https://www.ischool.berkeley.edu/courses/info/253a
- 462