It was little bit low level. What were some objects that we looked at? →
We brought up a web server and served some simple static pages by… →
To create a Server object that
… We needed to do two things →
// bring in the http module
const http = require('http')
// create a server object that listens on port 3000
// ...and bind the handleRequest function to a requeset event
http.createServer(handleRequest).listen(3000)
We created a callback function to handle requests. What were the two arguments that it could take? →
req
)res
)
function handleRequest(req, res) { ... }
What did we use the IncomingMessage (request) object for? →
We mainly just used it to determine what url the client was attempting to request:
if(req.url == '/') ..
What did we use the Response object for? →
We used it to send back the response headers and body. What were two methods that we used on it? →
res.writehead(200, {'content-type':'text/plain'});
res.end('hello');
So, all together …
const http = require('http');
http.createServer(handleRequest).listen(3000);
console.log('starting server on port 3000';
function handleRequest(req, res) {
if(req.url == '/') {
res.writehead(200, {'content-type':'text/plain'});
res.end('hello');
} else {
res.writeHead(404, {'Content-Type':'text/plain'});
res.end('Not Found');
}
}
We modified our program so that it served static files. How did we do that (what module and method did we use?) →
We used the fs
module.
…and we used the readFile
method, which takes a path and a callback.
// within our serveStatic function
fs.readFile(path, function(err, data) { ... });
Our serveStatic
function did two things:
function serveStatic(res, path, contentType, resCode) {
fs.readFile(path, function(err, data) {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('500 - Internal Error');
} else {
res.writeHead(resCode, { 'Content-Type': contentType });
res.end(data);
}
});
}
We modified our request handling callback to use our new serveStatic
function instead of sending back a response directly.
function handleRequest(req, res) {
if (req.url === '/') {
serveStatic(res, './public/index.html', 'text/html', 200);
} else if (req.url === '/about') {
serveStatic(res, './public/about.html', 'text/html', 200);
}
// remainder of function definition omitted for brevity
}
Well… maybe some if it was not so great. What were some challenges in writing that program, and what were some missing features? →
Let's use a server side web framework. A web framework is a set of tools, libraries or software that reduces the overhead of developing web applications.
Some features that a web framework may provide are: →
Web frameworks can be very featureful:
Web frameworks can also be very minimal:
Web frameworks can generally be categorized in this manner, or fall somewhere inbetween.
There are a lot of options for web frameworks, and they vary by language:
The highlighted ones are microframeworks.
Generally, a microframework, or a minimal web framework:
We'll be using Express 4. A little bit about Express… →
http
moduleSome features that Express comes with:
response.sendFile
response.redirect
request.ip
Some things that Express doesn't do (on its own):
Some use cases for express
How do we install express? →
npm install express
What if we want to save it as a dependency of our project? →
// if you don't already have a package.json
npm init
// install express and save dependency to package.json
npm install express --save
Hello World
const express = require('express');
const app = express();
app.get('/', function(req, res){
res.send('hello');
});
app.listen(3000);
console.log('Started server on port 3000');
Let's try adding another url. The URL should be /faq. →
app.get('/faq', function(req, res) {
res.send('you has q, i has answer');
});
Try navigating to your app with… →
http://localhost:3000/
http://localhost:3000/faq
http://localhost:3000/faq?question=1
http://localhost:3000/faq/
http://localhost:3000/faQ
http://localhost:3000/nope
What are some differences with our previous implementation using only node's http module? →
// require the express module
const express = require('express');
// create our express app
const app = express();
// use a router to bind a callback, a request handler
// to a particular url
app.get('/', function(req, res){
// sends back a response; that is all
res.send('hello');
});
// listen on port 3000
app.listen(3000);
console.log('Started server on port 3000');
express() - creates a new express application
app.VERB(path, [callback]…, callback) - defines routes
get
)res.send([body]) - send a response
text/html
application/json
Of course, you can still manipulate headers before sending…
res.set() - set a response header
This code will allow any file found in the public directory in your project to be served as a static file!
const path = require("path");
const publicPath = path.resolve(__dirname, "public");
app.use(express.static(publicPath));
No more individual urls (YES!)
Use the path module to create a path that specifies where your static files are located.
// bring in the path module
const path = require("path");
// create a cross-platform compatible path name (don't just use public)
const publicPath = path.resolve(__dirname, "public");
Use the built-in static files middleware to serve up any file in publicPath
app.use(express.static(publicPath));
Serving flat HTML files is nice and all, but is it adequate for building all sorts of web applications? →
Well, we want to serve dynamic content. That is, our web application will be generating html on-the-fly.
To do this, we'll need a way to: →
There are many templating solutions that we can use, both on the server side and the client side.
(slightly less to learn … but definitely feel free to use jade/pug instead)
First, install the express handlebars module:
npm install hbs --save
And in your code, bring in handlebars for templating:
app.set('view engine', 'hbs');
Render a template!
res.render('index', { "greeting":"HELLLOOOO" });
In views/layout.hbs
…
(Notice 3 curly braces!)
{{{ body }}}
In views/viewname.hbs
… drop in your content
{{ greeting }} world!