Express.js

Installation

To set up Express, create a Node project with:

# check is node is installed
node --version

# make node project
mkdir my-node-express-app
cd my-node-express-app
npm init

# install express.js (in the node project my-node-express-app)
npm install --save express

Basic Routing

  • API endpoint: a point at which an API connects with a software program.

  • Routing: how an app responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method

  • The HTTP methods which are supported are, GET, POST, PUT, DELETE

  • Routes have the following structure:

    app.METHOD(PATH, HANDLER)

    Where:

    ​ (app is an instance of express; 'const app = express()'),

    ​ (METHOD is an HTTP REQUEST METHOD),

    ​ (PATH is a path on the server),

    ​ (HANDLER is the callback function when the route is matched)

    ​ also called Controller

  • Simple Routes for the Hello World App above:


Serving Static Files

  • To serve static files such as images, CSS files, and JavaScript files, use the express.static built-in middleware function in Express:

    Now, you can load the files that are in the public directory:

    To use multiple static assets directories, call the express.static middleware function multiple times:

  • If you run the express app from another directory, it’s safer to use the absolute path of the directory that you want to serve:


Routing In-Depth

  • You define routing using methods of the Express app object that correspond to HTTP methods; for example, app.get() to handle GET requests and app.post to handle POST requests.

  • You can also use app.all() to handle all HTTP methods and app.use() to specify middleware as the callback function.

Route Methods

  • A route method is derived from one of the HTTP methods, and is attached to an instance of the express class (usually 'app'). Some basic routes:

  • There is a special routing method, app.all(), used to load middleware functions at a path for all HTTP request methods. Ie. the following handler is executed for requests to the route “/secret” for any HTTP verb:

Route Paths

  • Route paths, in combination with a request method, define the endpoints at which requests can be made. Query strings are not part of the route path. Some route paths:

Route Parameters

  • Route parameters are named URL segments that are used to capture the values specified at their position in the URL

  • The captured values are populated in the req.params object, with the name of the route parameter specified in the path as their respective keys.

  • To define routes with route parameters, simply specify the route parameters in the path of the route as shown below:

  • Since the hyphen (-) and the dot (.) are interpreted literally, they can be used along with route parameters for useful purposes:

Route Handlers

  • Also called controllers, route handlers are the callback functions that behave like middleware to handle a request. Route handlers can be in the form of a function, an array of functions, or combinations of both (see here).

  • Handlers usually have 3 parameters: a response object, a request object, and a next().

Response Methods

  • The methods on the response object (res) in the following table can send a response to the client, and terminate the request-response cycle.

  • If none of these methods are called from a route handler, the client request will be left hanging

    Method
    Description

    Prompt a file to be downloaded. res.download('/report-12345.pdf')

    End the response process. res.end() res.status(404).end()

    Send a JSON response. res.json({ user: 'tobi' }) res.status(500).json({ error: 'message' })

    Redirect a request. res.redirect('http://example.com') res.redirect(301, 'http://example.com')

    Render a view template.

    Send a response of various types. (When parameter is String, the method sets the Content-Type to “text/html”) (When the parameter is an Array or Object, Express responds with the JSON representation)

    Set the response status code and send its string representation as the response body. res.sendStatus(404)

    Sets the response’s HTTP header field to a given value. res.set('Content-Type', 'text/plain')

  • app.route() - used to create chainable route handlers for a given route path. Organizes the code with the routes:

express.Router (SUB ROUTING)

  • Use the express.Router class to create modular, mountable route handlers

  • A Router instance is a complete middleware and routing system; referred as a “mini-app”

  • This helps with abstraction and organizing code.

  • The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app:

    You would load ('mount') the sub route onto the main app much like you load a middleware: with the app.use function. But now, you pass in the route to load it onto, then pass the subroute.


CRUD

  • Create-Read-Update-Delete operations work perfectly with REST since there's a one-to-one correspondence with the HTTP verbs and CRUD:

    [C]reate = app.post()

    [R]ead = app.get()

    [U]pdate = app.put()

    [D]elete = app.delete()

(.post and .put only differ in their intentions; both post data, but .put expects to cause an update not a creation)


Route Order

  • If you have 2 endpoints/routes with the same verb, the one higher up will be executed since Node is top-down execution.


Sub Routing

  • You can have branches of routes (sub routes)


Middleware

  • Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle.

  • The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.

  • Middleware functions can perform the following tasks

    • Execute any code, Make changes to the req&res objects, End the request-response cycle, Call the next middleware in the stack.

If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging

  • ie. a middleware function called myLogger simply prints “hi” on GET requests:

There are many useful third party middlewares you can download namely body-parser.


Template (View) Engines with Express

A template engine enables you to use static template files in your application.

At runtime, the template engine replaces variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page.

Some popular template engines that work with Express are Pug (formerly known as Jade), Mustache, and EJS.

  • res.render('filename') - used to render (ie. upload an html file) to the client side. This function assumes a Model-View-Controller Structure (MCV) project structure, so when you call res.render('index'), it will look inside a views folder for a filename of 'index' (index.html; don't include file extension in function call). So now, you can render different HTML pages for different routes using this method.

To use EJS:

  1. install ejs: npm i ejs --save

  2. create a folder named 'views' with file you want to render (ie. nfl.ejs); the file extension must be .ejs (it's still HTML but with a little programming language in it- kinda like jsx)

  3. app.set('view engine', 'ejs')

  4. res.render('nfl')

![Screen Shot 2021-12-12 at 9.24.33 PM](/Users/dev/Library/Application Support/typora-user-images/Screen Shot 2021-12-12 at 9.24.33 PM.png)


Middleware References

> body-parser ( deprecated; now use -> express.json() )

  • allows us to read the "body" of an incoming JSON object. But it's deprecated.

  • Now, we can simply use express.json():

> cors

  • CORS stands for Cross-Origin Resource Sharing. It allows us to relax the security applied to an API. This is done by bypassing the Access-Control-Allow-Origin headers, which specify which origins can access the API.

  • The three parts that form an origin are protocol, domain, and port. (http [protocol] localhost [domain] :3000 [port]). There are servers that host APIs and ensure that info is delivered to websites and other end points. Therefore, making cross-origin calls. read more here.

> morgan

  • simplifies the task of logging HTTP requests and errors to and from your application.

    And now all you need in your app is (either 'dev' or 'tiny'):

    the 'dev' parameter can be swapped with 'combined', 'common', 'short', 'tiny'- each is a different format of the log:

Last updated