First try with Express
Tags: node, javascript
Published: 2019-11-27 13:16:39

While working as automation QA using NodeJS, I always have big interest in how to build up a web application and recently I have decided to give it a try with the de-facto Express framework.

---

Starting with the basic guide from Mozilla (https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs), I find it very coherent and easy to follow. But there is a trouble that the guide is using the callback style which is both convenient and troublesome to use in my opinion. 

```javascript
// Display list of all Books.
exports.book_list = function(req, res, next) {

  Book.find({}, 'title author')
    .populate('author')
    .exec(function (err, list_books) {
      if (err) { return next(err); }
      //Successful, so render
      res.render('book_list', { title: 'Book List', book_list: list_books });
    });
    
};
```

Besides, I am using Promise and async-await style for my automation test suites at [RealStake](https://realstake.net), so I try converting the guide to the latter style for easier controlling the code flow.

```javascript
module.exports = {
    getList: async (req, res, next) => {
        try {
            const bookInstanceList = await BookInstance.find({})
                .populate('book')
                .exec();
            res.render('bookInstanceList', {
                title: 'Book Instance List',
                bookInstanceList,
            });
        } catch (err) {
            next(err);
        }
    },
}
```

And the experience is quite amazing because I can achieve both the basic understanding of how Express works and understand more about callback using.

---

After finishing the guide, I try to relate to the current project at my company and plan to add more features like JWT authentication, Redis storage, etc. to explore more on building a real application. Then I make up my own Trello board (https://trello.com/b/K0mY1Jpo/learn-express) to define and monitor what I have been doing and what I will implement.

![trello](https://thepracticaldev.s3.amazonaws.com/i/vdsqa6fvsbayxih9q1ui.png)

By making use of the Trello board, it is easier for me to control my learning flow. It also makes me feel more organized :D

So far I have been able to implement more routes to my small local library app such as:
- JWT authentication for log in
- blacklist JWT token for log out 
- register new account and send activation email via Sendgrid
- ...

---

And for deployment, I already have some experience with using Zeit for my automation workflow with Asana (https://dev.to/trannguyenhung011086/how-i-sync-github-pull-request-status-to-asana-task-flow-nl2). 

So at first, I deployed my app as a normal Express server.

```javascript
const config = require('./common/config');
const mongo = require('./loaders/mongo');
const redis = require('./loaders/redis');
const app = require('./loaders/express');

app.listen(config.port, () =>
    console.log(`App listening on port ${config.port}`),
);
```

Then I found an article about using Zeit for serveless functions (https://medium.com/@bmikkelsen22/designing-a-serverless-express-js-api-using-zeit-now-6e52aa962235) and tried to change my code a bit. 

It is quite surprising that such task does not take so much effort because Zeit already see an Express app as a function by using **@now/node** option for deployment. I just need to map routes to those functions.

```javascript
// now.json
{
    "version": 2,
    "name": "learn-express",
    "builds": [{ "src": "/api/*.js", "use": "@now/node" }],
    "routes": [
        { "src": "/catalog", "dest": "/api/catalog.js" },
        { "src": "/catalog(/.*)", "dest": "/api/catalog.js" },
        { "src": "/user(/.*)", "dest": "/api/user.js" },
        { "src": "(/.*)", "dest": "/api/home.js" }
    ],
}

// api/catalog.js
const app = require('./setup');
const catalogRouter = require('../routes/catalogRoute');
const authMiddleware = require('../middlewares/authMiddleware');

app.use(
    '/catalog',
    authMiddleware.validateToken,
    authMiddleware.refreshToken,
    catalogRouter,
);
app.use('*', (req, res) => {
    res.status(404).send('Page not found!');
});

module.exports = app;
```

The whole code can be found at https://github.com/trannguyenhung011086/learn-express.

---

To sum up, by learning to build an application with Express, I gain more insight in development works and feel really hooked with pushing my Node JS skills as far as possible. And I will definitely continue exploring more in the path of building web application.