Intro to Express
Beginning with the End in Mind
- List the Fundamental Capabilities of Web Frameworks
- Create a Basic Express Web App
- Define Basic Routes
- Respond to HTTP Requests
- Render Dynamic Views
- Describe REST and list the various routes
- Create an Index route
- Install JSONView to make viewing JSON easier
- Create a Show route
- Enhance the data in your data array
- Define MVC and explain why it matters
- Move our data into a separate file
- Move our presentation code
Setup
This unit we will be building 2 applications together The Fruits App and The Captain's Log. Then you will build a Pokemon Mini Project & Mongoose Store App in breakout rooms and Culminate with a Blog Project that you will present. Fruits will be turned in at the end of the Unit so make sure you follow along.
- Create a folder called
fruitsand then change into it
$ mkdir fruits
$ cd fruits- Create a file inside this folder called
server.js
$ touch server.js- Make three folders
$ mkdir models views controllers- Then create a
package.jsonand accept the defaults using this command:
$ npm init -y- Open the project's folder in VS Code.
The Three Fundamental Capabilities of Web Application Frameworks
-
Web Application Frameworks have three capabilities fundamental to writing a back-end web application:
- The ability to define routes
- The ability to process HTTP requests using middleware
- The ability to use a view engine to render dynamic templates
- Over the next few lessons, you will learn about how the Express framework implements these three fundamental capabilities.
Express Framework - Intro
- Express is the most popular web framework for Node.js.
- It is minimalistic and lightweight, especially when compared to massive frameworks like Django and Rails.
- Express uses Node's built-in HTTP module to listen for, and respond to, HTTP requests - Express simply adds those three web application capabilities on top of Node
Install the Express Module
-
Let's use
npmto install the Express module in this project:$ npm i expressNote that
iis a shortcut forinstall
Express - Hello World!
-
Let's write the obligatory "Hello World!" application:
// Load express const express = require('express'); // Create our express app const app = express(); // Define a "root" route directly on app // Tomorrow, we'll use best practice routing app.get('/', function (req, res) { res.send('<h1>Hello World!</h1>'); }); // Tell the app to listen on port 3000 // for HTTP requests from clients app.listen(3000, function () { console.log('Listening on port 3000'); });
-
Run the app:
$ npm start - Browsing to
localhost:3000will hit our app's root route that we defined and return "Hello World!". - Using DevTools, we will find that despite just sending back the text of
<h1>Hello World!</h1>, the browser "built" a minimal HTML document to display it in. - The
sendmethod is a general purpose way to respond to the request, however, soon we'll be using more specific methods.
Basic Structure of Express App
- Here is a helpful outline of what a typical Express app does - let's put this guide right in our
server.js:
// Require modules
const express = require('express');
// Create the Express app
const app = express();
// Configure the app (app.set)
// Mount middleware (app.use)
// Mount routes
app.get('/', (req, res) => {
res.send('<h1>Hello World!</h1>');
});
// Tell the app to listen on port 3000
app.listen(3000, function() {
console.log('Listening on port 3000');
});Our First Route
-
Let's replace the content we just sent from our route with something else.
// Mount routes app.get('/', (req, res) => { res.send('<h1>Hello Express</h1>'); }); - Refreshing the page will reveal that it didn't work! This is because we have to restart the server, or...
Nodemon
nodemonis a popular development tool used for automatically restarting our Express app when we save changes.- lets go to
package.jsonand update thescriptsobject - lets add a new key to the object that says
"dev": "nodemon" - Now, thanks to the
mainkey inpackage.json, we can start the server by simply typingnpm run dev. - Now lets stop the server currently running with
npm startby typingctrl + cand then runnpm run dev - Let's move on to routing...
Our First Route (Cont)
- Like most web frameworks, Express uses the
HTTP Methodand thePathof the HTTP request to match a route defined in the application. - In our first route, we defined a route using the
getmethod on the Expressappobject. - The
getmethod defines a route that listens for aGETrequest. There are other methods such aspost,putanddelete, that map to the other HTTP verbs. - The first argument provided to
app.get,/, defines the path for the route. In this case the root of the application, i.e., just the host name likelocalhost:3000. - In Express, all strings used to define a path should start with a forward-slash character (
/). - In tomorrow's Express lesson, we'll learn a preferred way of defining routes using the Express
Routerobject, but you need to be aware of defining routes this way as well.
The Route's Callback
-
The second argument provided to
app.get()is a callback function:app.get('/', (req, res) => { res.send('<h1>Hello From Fruits App</h1>'); }); - Express will execute route's callback function only when a matching HTTP request (HTTP Method + Path) is received.
-
The route's callback function:
app.get('/', (req, res) => { res.send('<h1>Hello From Fruits App</h1>'); });defines two parameters:
req&res req: Represents Express's request object, andres: Represents Express's response object- Express provides those two objects as arguments when it invokes the callback.
- The
requestobject has properties and methods used to access information regarding the current HTTP request, including any data being sent from the browser. - The
responseobject contains properties and methods used to end the request/response cycle - like we've done so far using theres.sendmethod.
Practice - Define Another Route (3 mins)
- Define another route that matches a
getrequest to a path of/homethat sends a text response of<h1>Home Page</h1>. - Test it by browsing to
localhost:3000/home.
Review Question - Routing
- Is it okay to define more than one route on the same path?
For example:
app.get('/fruits', (req, res) => {
res.send("Here's a list of fruit...");
});
app.post('/fruits', (req, res) => {
res.send('Thanks for buying a fruit!');
});Ways to Respond to a Request
- So far we have responded in our route handler (callback) code by using the
res.sendmethod. - The Express docs for the Response object explains the other ways to respond to the HTTP request.
-
Here are the methods we'll use the most:
res.render()- Render a view template and send the resulting HTML to the browser.res.redirect()- Tell the browser to issue anotherGETrequest.res.json()- Send a JSON response (used when we build an API).
Rendering A View
const fs = require('fs') // this engine requires the fs module like we did Saturday
app.engine('evelyn', (filePath, options, callback) => { // define the view engine called hypatia
fs.readFile(filePath, (err, content) => {
if (err) return callback(err)
// this is an extremely simple view engine we'll be more complex later
const rendered = content.toString()
.replace('#title#', `<title>${options.title}</title>`)
.replace('#message#', `<h1>${options.message}</h1>`).replace('#content#',`<div>${Array.isArray(options.content)? options.content.map(item => `<li>${item}</li>`) : options.content }</div>` )
return callback(null, rendered)
})
})
app.set('views', './views') // specify the views directory
app.set('view engine', 'evelyn') // register the evelyn view engineAfter the code above
-
Make a file called
template.evelynin theviewsfolder<head> #title# </head> <body> <header>#message#</header> #content# </body>
Then in the server.js
app.get('/', (req, res) => {
res.render('template', { title: 'I am DJ Khaled', message: 'We The Best!', content: 'All I Do is Win' })
})
app.get('/about-me', (req, res) => {
res.render('template', { title: 'DJ KHALED', message: 'It Breaks My Heart!', content: 'They Ain\'t Believe in Us But God Did' })
})
app.get('/another-one', (req, res) => {
res.render('template', { title: 'We The Best', message: 'Who The Best! We!!!', content: 'We Taking Over, Major Key Alert, Y\'all know who it is, All I do is win, God Did!!!' })
})View the following links in the browser
http://localhost:3000/http://localhost:3000/about-mehttp://localhost:3000/another-one
Essential Questions Back to The Professionalism
❓ When we define routes in a web app, we are mapping HTTP requests to ____.
❓ What method do we call to render a view and on what object does that method exist?