Categories
Express JavaScript

Guide to the Express Application Object

The core part of an Express app is the Application object. It’s the application itself.

In this piece, we’ll look at the methods of the app object and what we can do with it.


app.METHOD(path, callback [, callback …])

This method routes an HTTP request. METHOD is a placeholder for various routing methods that Express supports.

It takes the following arguments:

  • path — It can be a string or regex representing paths or patterns of paths. The default is /.
  • callback — a function to handle requests. It can be a middleware function, a series of them, array of them, or a combination of all of the above.

The following routing methods are supported by Express:

  • checkout
  • copy
  • delete
  • get
  • head
  • lock
  • merge
  • mkactivity
  • mkcol
  • move
  • m-search
  • notify
  • options
  • patch
  • post
  • purge
  • put
  • report
  • search
  • subscribe
  • trace
  • unlock
  • unsubscribe

All methods take the same arguments and work exactly the same way. So app.get and app.unlock are the same.


app.param([name], callback)

app.param adds callback triggers for route parameters. name is the parameter or an array of them. callback is a callback function.

The parameters of the callback are the request object, response object, next middleware function, the value of the parameter, and the name of the parameter in the given order.

For example, we can use it as follows:

The code above will get the id URL parameter when it exists with the app.param callback.

Then in the callback, we get id to req.id and call next to call our route handler in app.get.

Then we call res.send(req.id); to send the response with req.id, which we set earlier.

Note that id in app.param has to match :id with the route handlers.

We can pass in an array of parameters that we want to watch for:

Then if we make a request for /1/foo, we’ll get 1 and foo one at a time as the value of the value parameter.


app.path()

app.path returns the path of mounted apps as a string.

For example, we can use it as follows:

Then we get '' for app.path(), '/foo' for foo.path(), and '/foo/bar' for bar.path() since we mounted foo to app and bar to foo.


app.post(path, callback [, callback …])

We can use the app.post method to handle POST requests with the given path by passing in a callback route handler.

It takes the following arguments:

  • path — It can be a string or regex representing paths or patterns of paths. The default is /.
  • callback — a function to handle requests. It can be a middleware function, a series of them, array of them, or a combination of all of the above.

For example, we can use it as follows:

Then when we make a POST request with a client like Postman, we should see “POST request made.”


app.put(path, callback [, callback …])

We can use the app.put method to handle PUT requests with the given path by passing in a callback route handler.

It takes the following arguments:

  • path — It can be a string or regex representing paths or patterns of paths. The default is /.
  • callback — a function to handle requests. It can be a middleware function, a series of them, array of them, or a combination of all of the above.

For example, we can use it as follows:

Then when we make a PUT request with a client like Postman, we should see “PUT request made.”


Conclusion

We can intercept the parameters sent from requests with the app.params method.

To listen to POST requests, we can use the app.post method. To listen to PUT requests, we can use the app.put method.

app.path lets us get the path of mounted apps.

app also has a long list of methods for listening to all kinds of requests.

Categories
Express JavaScript Nodejs

More About Routing with Express

Routing is the most important part of a back end application. Express allows us to route URLs to our route handler code easily.

In this article, we’ll look at how to create different kinds of routes with Express.

Handling All Requests

We can use the app.all method to handle all request methods. To use it, we can write something like the following:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.all('*', (req, res, next) => {  
  console.log('route called');  
  next();  
})

app.get('/', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

The app.all call above will be invoked when any method or URL is sent. It’ll log 'route called' and then call next to call the specific route handler for that route.

Non-Letter Symbols

Express can match routes with non-letter symbols. For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/foo.bar', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then when we make a GET request to foo.bar then we get hi .

Special Characters

Optional Character

If the ? is in a URL path, then it’s considered an optional character. For example, ab?c matches ac or abc .

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab?c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then when we make a request to /ac or /abc , we get hi .

One or More Character

If a URL has a + sign, then it’ll match one or more of the character preceding it.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab+c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then when making a request to /abc , /abbc , /abbbc and so on, we’ll get hi .

Wildcard

The * in the URL is a wildcard character.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab\*c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then we put anything between ab and c in the URL and get the hi response.

Optional Character Group

A character group is optional if it’s surrounded by parentheses and has a ? after it.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab(cd)?ef', (req, res) => {  
  res.send('hi');  
})
app.listen(3000, () => console.log('server started'));

Then when we go to /abcdef or /abef , we get hi .

Regular Expressions

We can also use regular expressions as route paths. For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get(/\/a/, (req, res) => {  
  res.send('hi');  
})
app.listen(3000, () => console.log('server started'));

Then when we make a request to /a , we get hi .

To get hi when we make any request with path that ends with foo , we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get(/\/.\*foo$/, (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Route Parameters

We can designate parameters by writing a colon before the key name of the parameter.

For example, we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/:name/:age', (req, res) => {  
  res.send(req.params);  
})

app.listen(3000, () => console.log('server started'));

Then we get the following response:

{"name":"Mary","age":"10"}

:name and :age are interpreted as route placeholders. req.params will use them as the keys without the colon. Then whatever is set in the place of the placeholders will be the corresponding values.

Route Handlers

The callback in the second argument of the app.get above are route handlers. The same can be done for POST, PUT and DELETE requests by replacing app.get with app.post , app.put and app.delete respectively.

We can chain multiple handlers together with the next function. For example, we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/',  
  (req, res, next) => {  
    console.log('handler 1 called');  
    next()  
  },  
  (req, res) => {  
    console.log('handler 2 called');  
    res.send();  
  })

app.listen(3000, () => console.log('server started'));

Then we should see:

handler 1 called  
handler 2 called

in the console.log output.

We call the next function which originates from the route handler’s parameter to call the next route handler function.

Conclusion

Routing with Express is simple. We can use strings or regular expressions to specify our route paths.

Some characters in string paths like ? , +, or * are special characters for paths with optional characters or wildcards.

Placeholders for route parameters are specified by using a colon in front of the placeholder name.

We call next to chain multiple route handlers together.

Categories
Express JavaScript Nodejs

More About the Express Application Object

The core part of an Express app is the Application object. It’s the application itself.

In this article, we’ll look at the methods of the app object and what we can do with it.

Methods

app.disabled(name)

The method returns true if the given setting is disabled.

For example, if we have:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));

app.disable('foo');

app.get('/', function (req, res, next) {  
  res.json({ fooDisabled: app.disabled('foo') });  
})

app.listen(3000, () => console.log('server started'));

Then we get:

{"fooDisabled":true}

since we called app.disable(‘foo’);

On the other hand, if we called app.enable(‘foo’); then we get:

{"fooDisabled":false}

app.enable(name)

We can use enable to set the setting with the given name to true .

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));

app.enable('foo');

app.get('/', function (req, res, next) {  
  res.json({ fooDisabled: app.disabled('foo') });  
})

app.listen(3000, () => console.log('server started'));

Then we get:

{"fooDisabled":false}

since we called enable with 'foo' passed in.

app.enabled(name)

The enabled method returns if a setting with the given name is enabled. For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.enable('foo');
app.get('/', function (req, res, next) {  
  res.json({ fooDisabled: app.enabled('foo') });  
})

app.listen(3000, () => console.log('server started'));

Then we get {“fooDisabled”:true} since we called app.enable(‘foo’); .

app.engine(ext, callback)

We call the engine method to set the template engine that we use to render our HTML output.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('views', './views');

app.get('/', (req, res, next) => {  
  res.render('index', { people: ['geddy', 'neil', 'alex'] })  
})

app.engine('html', require('ejs').renderFile);  
app.set('view engine', 'ejs');  
app.listen(3000, () => console.log('server started'));

Then we can add our template to views/index.ejs as follows:

<%= people.join(", "); %>

and we get:

geddy, neil, alex

displayed.

The callback should have the parameters, path , options , and callback .

app.get(name)

We can use the get method to get the value of a setting with the given name.

For example, if we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('title', 'Foo');
app.get('/', (req, res, next) => {  
  res.send(app.get('title'));  
})

app.listen(3000, () => console.log('server started'));

Then we get Foo displayed since we called:

app.set('title', 'Foo');

app.get(path, callback [, callback …])

The get method lets us pass in a route handler callback or a series of them to handle get requests with the given path .

It takes the following arguments:

  • path — it can be a string or regex representing paths or patterns of paths. The default is / .
  • callback — a function to handle requests. It can be a middleware function, a series of them, array of them, or a combination of all of the above

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('title', 'Foo')
app.get('/', (req, res, next) => {  
  res.send('GET request made');  
})
app.listen(3000, () => console.log('server started'));

app.listen(path, [callback])

It starts a UNIX socket and listens to connects on the given path.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('title', 'Foo')app.get('/', (req, res, next) => {  
  res.send('hi');  
})

app.listen('/tmp/sock');

Then when the /tmp/sock socket isn’t in use, we can start our app by listening to this socket.

app.listen([port[, host[, backlog]][, callback])

This listen method listens for connects on the given host and port.

If the port is omitted or it’s 0, then the operating system will assign an arbitrary port for it to listen to.

We can pass the Express app object to the http.createServer to listen to connections as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const http = require('http');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res, next) => {  
  res.send('hi');  
})

http.createServer(app).listen(3000);

This lets us easily provide both an HTTP and HTTPS version of the app with the same code base.

app is actually a function so we can pass it into http.createServer as a callback.

app.listen() returns an http.Server object and it’s a convenience method for the following:

app.listen = function () {  
  const server = http.createServer(this)  
  return server.listen.apply(server, arguments)  
}

So we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const http = require('http');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res, next) => {  
  res.send('hi');  
})

app.listen = function () {  
  const server = http.createServer(this)  
  return server.listen.apply(server, arguments)  
}

app.listen(3000);

Conclusion

We can check is a setting is set to false with the disabled method.

To process GET requests, we can use the get method. It takes a route path and one or more route handler callbacks.

Finally, we have the listen method to listen for connections from UNIX sockets or given host and port. app can be passed into Node.js’ http.createServer method as a callback function since app is actually a function.

Categories
Express JavaScript Nodejs

Using Express Middleware

Middleware functions are functions that have access to the request and response objects, and the next function for call the next middleware.

In this article, we’ll look at what Express middleware does and how we can use them.

Characteristics of Middleware

Middleware functions can run any code, make changes to the request and response object, end the request-response cycle, and call the next middleware in the stack.

Application-Level Middleware

We can run middleware that are used when any routes are called by passing it to the app.use method as a callback.

If we want to a middleware function to be called only when a request of one request method is called, then we can pass it to the app.METHOD method as a callback. Where METHOD is get , post , put , delete , etc.

For example, we can write a middleware function and pass it into app.use to log the request method of a request as follows:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.use((req, res, next) => {  
  console.log(req.method);  
  next();  
});

app.get('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));

Then we should get GET logged when we make a GET request to / .

We can restrict the middleware function to be run only on GET requests and to the path / by writing:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  console.log(req.method);  
  next();  
});

app.get('/', (req, res) => {  
  res.json();  
})

app.post('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));

Then we only see GET logged when we make GET requests to the / path.

Running a Series of Middleware Functions

We can use the next method to call the next middleware function in the series, so we can use it to chain middleware function calls together.

For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.use(  
  (req, res, next) => {  
    console.log('middleware 1 called');  
    next();  
  },  
  (req, res, next) => {  
    console.log('middleware 2 called');  
    next();  
  }  
);

app.get('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));

Then we see:

middleware 1 called  
middleware 2 called

from the console.log output of each middleware.

If we send a response in our middleware, then the next one won’t get called. For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.get('/',  
  (req, res, next) => {  
    next()  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

app.get('/',  (req, res, next) => {  
  res.end();  
})

app.listen(3000, () => console.log('server started'));

Then we get the output ‘Second middleware’ when we make a request to / .

Our route handler in:

app.get('/', function (req, res, next) {  
  res.end();  
})

wasn’t called.

We can call next as follows:

next('route');

to go straight to our route handler, bypassing the other middleware functions down the line.

For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.get('/:id',  
  (req, res, next) => {  
    if (req.params.id === '0') {  
      next('route');  
      return;  
    }  
    next();  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

app.get('/:id', (req, res, next) => {  
  res.end(req.params.id);  
})

app.listen(3000, () => console.log('server started'));

Then when we make a request to /0 , then we get 0 . Otherwise, we get ‘Second Middleware’ outputted.

Router Level Middleware

Router level middleware works the same way as app-level middleware, but they’re bound to the instance of the express.Router() instead of the express instance.

For example, we can use it as follows:

const express = require('express')  
const app = express()  
const router = express.Router();
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.use((req, res, next) => {  
  req.requestTime = new Date();  
  next();  
})

router.get('/', (req, res, next) => {  
  res.json(req.requestTime);  
})

app.use('/', router);

app.listen(3000, () => console.log('server started'));

Then when we make a request to the / route we get back the timestamp as the output.

Chaining middlewares and skipping routes work the same way as app-level middleware. For example, we can write the following to chain middlewares as follows:

const express = require('express')  
const app = express()  
const router = express.Router();

app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.use(  
  (req, res, next) => {  
    console.log('middleware 1 called');  
    next();  
  },  
  (req, res, next) => {  
    console.log('middleware 2 called');  
    next();  
  }  
)

router.get('/', (req, res, next) => {  
  res.json();  
})

app.use('/', router);

app.listen(3000, () => console.log('server started'));

Then we see:

middleware 1 called  
middleware 2 called

from the console.log output of each route middleware.

We can use next('route') to skip to the route as follows:

const express = require('express')  
const app = express()  
const router = express.Router();
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.get('/:id',  
  (req, res, next) => {  
    if (req.params.id === '0') {  
      next('route');  
      return;  
    }  
    next();  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

router.get('/:id', (req, res, next) => {  
  res.end(req.params.id);  
})

app.use('/', router);
app.listen(3000, () => console.log('server started'));

Then when we make a request to /0 , then we get 0 . Otherwise, we get ‘Second Middleware’ outputted.

Conclusion

Using Express middlewares is simple. We can either pass them into app.use to make the middleware run for all request methods, or app.METHOD to make them run for the given method.

We can call next to call the next middleware, and call next('route') to call the route handler directly from a middleware.

Everything applies to both route and app-level middleware, except that they bind to the express.Router() and express() respectively.

Categories
Express JavaScript Nodejs

Using Template Engines with Express

To render an HTML response with an Express route, we should return it as a template with the variable interpolated rather than return it directly as an HTML string.

Templates are convenient and we can use them in a much more flexible way than HTML strings.

In this article, we’ll look at how to set the template engine of our app, and returning HTML responses.

Choosing Template Engines

We can use popular template engines with Express, like Pug, Mustache, and EJS. The default for the Express application generator is Jade, but we can use the other ones listed as well.

To render template files, we can set the application settings. To set the templates folder, we can set the views property by writing the following:

app.set('views', './views')

It’ll set the templates folder to the views directory of our app.

Also, we can set the view engine we want to use by setting the view engine property as follows:

app.set('view engine', 'pug')

To install the template engine library, we can run something like the following:

npm install pug --save

The command above will install pug view engine for us to use.

Rendering Items with Template Engines

We can use the res.render method to render our variables to our templates.

First, we create the views folder to store our templates as we set the ./views folder to be our templates folder.

Since we chose to use Pug as our template engine, the template files should have the .pug extension.

Inside the views folder, create an index.pug and then put:

html  
  head  
    title= title  
  body  
    h1= message

The title= and h1= are our tags and title and message are keys in which Express will use to get the values from in the object that we’ll pass to res.render .

Then we can create index.js in the same level as the views folder and add:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.set('views', './views');  
app.set('view engine', 'pug');

app.get('/', (req, res, next) => {  
  res.render('index', { pageTitle: 'Hello', pageMessage: 'Hello there!' });  
})

app.listen(3000, () => console.log('server started'));

In the code above, we called res.render to render an HTML response. The object:

{ pageTitle: 'Hello', pageMessage: 'Hello there!' }

will be passed to our index.pug template.

title will be the title in:

html  
  head  
    title= pageTitle  
  body  
    h1= pageMessage

message will be replaced by the 'Hello there!' . Anything right of the tag and the equal sign will be replaced by the value with the key given above.

In other words, pageTitle and pageMessage properties’ values’ are the ones that’ll go in between the title and h1 tags respectively.

So we get

and the title of our page will be 'Hello' .

Pug Syntax

We can have dynamic expressions other than variables. Loops and conditional expressions are part of Pug.

HTML Tags

Other HTML tags can be used with Pug.

For example, a link can be written as follows:

a(href='http://medium.com') Medium

In the code above Medium goes between the a tags and href=’http://medium.com' is the href attribute and value respectively.

Loops

We can also write loops with Pug. For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.set('views', './views');  
app.set('view engine', 'pug');

app.get('/', (req, res, next) => {  
  res.render('index', { pageTitle: 'Hello', pageMessages: ['Hi', 'Bye'] });  
})

app.listen(3000, () => console.log('server started'));

in index.js and:

html  
  head  
    title= pageTitle  
  body  
    ul  
      each pageMessage in pageMessages  
        li= pageMessage

in views/index.pug , then we would get:

Conditionals

We can also add conditional expressions to our Pug template. For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.set('views', './views');  
app.set('view engine', 'pug');

app.get('/', (req, res, next) => {  
  res.render('index', { pageTitle: 'Hello', user: { type: 'member' }   });  
})  
app.listen(3000, () => console.log('server started'));

in index.js and:

html  
  head  
    title= pageTitle  
  body  
    if user.type === 'anonymous'  
      p User type is anonyomous  
    else if user.type === 'member'  
      p User type is member  
    else  
      p User type is admin

in views/index.pug , then we get:

'User type is member'

since user.type in res.render is set to 'member' .

Conclusion

Rendering HTML response is easy if we use a template engine to do it. We can pass in an object in the second argument of res.render to pass in values that we want to display in the template.

With template engines, we can include loops, conditionals, and variables to make displaying dynamic content a breeze.