cats-app using NestJS

Couple of the dispatches prior to this we got introduced to nest and began our Oblog (a term cooked for observation log). We began clocking our observations on structure of framework by looking at the packge.json file.

We will continue observing working components of the framework in this dispatch. As we progress you are bound to notice lot of similarity with the angular framework. However, if you are not don’t get disheartened, we are in the path to gain some familiarity with angular framework in this process.

Our Oblog – Second dispatch

Other than the file package.json and a transactional file which indicates the lock i.e. package-lock.json. If you are curious towards what is package-lock.json it is the dependency tree of packages used by the application with exception of version numbers. Package.json file is allowed to contain ‘*’ in the version fields however package-lock.json contains the exact version number of the package used by the application.

Folder structure

Typical folder structure which you will get by executing the nest new project command –

 

app-name

|

|__ node_modules

|

|__ src

|

|__ test

|

|__ e2e //In cats-app

 

There will be couple of more config file which we will pick up to talk about later. For the cats-app this folder structure will be similar except for one addition which is the e2e expanding to End to End tests.

We did not yet log the modularity of the framework. Witnessed while executing the command nest new project one has the liberty to choose the framework for package management. Framework offers npm and yarn both. This modularity is further witnessed in the ability to select the http framework in the code which will observe in a short while.

There are three essential building blocks for the application. main.ts, app.module.ts, and app.component.ts. Together these files define the bootstrap strategy of the application you intend to build. Beyond these files you will also notice app.controller.spect.ts and app.service.ts files as well.

Questions leading to observations

For most of us who have worked on other technologies particularly Java, .NET, PHP would be distracted with the question where is the html file or template file or something equivalent of it which contains the markup for view?

This question quizzed me too. Answer to this natural question is in the laps of the modern web development approach. View are good to be handled by vanilla, fast http servers which marry data by making calls to HTTP services. It is these services which we are building using the nest framework. Thus, if it rejoices you – There will be no template or view or html file while we build application using nest framework.

Application or HTTP Service

This just embarked to me now as I finish the last statement. We have used the word “application” for the “HTTP services”. If you are purist you will already will have raised objection. An application is in entirety it cannot be just one tier which we can address as application. Also, it will be more appropriate if we address it as application service or HTTP service component.

For those familiar with angular framework would have connected the dots. Angular frontend acts as the view and Nest HTTP service component acts as app/service tier for the application and you could opt any of the RDBMS technology to persist data completing the following skeleton of APPLICATION –

Now the only difference you could tell from the diagram above to traditional web development approach is the choice of language. So, put simply these frameworks help you write web applications in JavaScript.

Language nuances

Similar to many other programming language entry point for the HTTP service component is located in main.ts as bootstrap function. There are few things at this juncture which is worth noting.

 

import {..} from ‘@nestjs/..’;

async function bootstrap() {

const app = await NestFactory.create(applicationModule);

await app.listen(3000);

}

 

First is the import statement which is characteristic of most of the TypeScript code. In ES2015

(ECMAScript 2015) language specification[1] which is also adorned by TypeScript a module is a logic grouping of types defined in the language. There were two type of modules earlier in TypeScript local & external. However, with advancement in the specification both types are now merged to be used as in the example above.

Best Practice It is recommended to use the import statement for each class or interface imported in the code. Though it lengthens the lines of code but it serves the purpose of emitting the dependency meta about the class / interface.

Other noteworthy syntax is the much celebrated feature of javascript async..await combo. async keyword marks the section of code to be processed by thread pool of node. Return value of the call is a promise which should be waited for completion. This is a handy feature of language which helps the developer avoid callback hell at the same time be able to run code asynchronously. All methods which are marked async should be awaited to reap the result of operations. Thus, you would notice the await in all the methods which have async keyword in its declaration. However, if there are operations that could be performed while processing is underway in the method marked async, you need not await. You should collect the promise and continue call the other method which can be processed without the result of the async method. This kind of operation will look like –

 

const typesOfCatFood = findAllCatFoodInIndiaAsync();

const catLongevity = getCatAgesInIndia();

Promise.all([typesOfCatFood, catLongevity]).then(function(values) {

return …;

}

 

Beyond the language specificity; the framework uses this function to initialize the HTTP server. Port 3000 is being used in the example to listen. Between initializing the nest framework and spinning up a

[1] ECMAScript 2015 specification – http://www.ecma-international.org/ecma-262/6.0/

HTTP server i.e. app.listen(3000) a configuration is performed for framework, i.e. pipe is added to perform validation of the input that comes in from the HTTP request.

The question that pops up is what are pipes? For the time being we can gulp the line and talk about it in a future context. Talking about the HTTP server is an interesting aspect and requires some explanation as well.

Backbone of HTTP service – The server

Typically, in node without a framework (nest) HTTP server is spun up using npm package http-server[1]. This is achieved as follows

 

const http = require(‘http’);

const server = http.createServer((request, response) => {

response.end(‘Hello world’);

});

server.listen(3000);

 

This way of booting server is straight forward. However, with a HTTP service tier this becomes complex quickly. E.g. imagine the basic scenario of request URL and the HTTP methods. You will have to create switch cases for each pattern of URL. Thus, comes the Express JS[2] platform to the rescue. This platform simplifies the configurations and helps developer build up a real-life HTTP server in node. With Express JS the above code should be written as

 

const http = require(‘express’);

const server = express();

server.get(‘/’, (req, res) => {

res.send(‘Hello World’);

}

server.listen(3000);

 

[1] http-server package in npm – https://www.npmjs.com/package/http-server

[2] Express JS home page – https://expressjs.com/

Beyond Express JS a similar framework used popularly is the Fastify[1] framework. Code is more or less similar to Express JS. Subtle differences start appearing as we dig into more advanced features. For now, let us collect the fact there are frameworks which help initialize a http server from nest framework.

Returning our attentions to the nest framework. Our HTTP service built using nest framework requires a http server to serve requests from the angular frontend. These frameworks help you accomplish exactly that goal. Nest being non-opioninated offers the ability to pick either off these platforms for the HTTP server i.e.

 

const httpServer = await NestFactory.create<NestFastifyApplication>(applicationModule);

 

There are two possibilities for the HTTP server platform inside Nest. One is NestExpressApplication another is the one described in the example above. Notice the Nest prefix to the types name. So, it is not straight forward to include the package and start using in the nest framework. It needs to have known types created in the nest framework. The reason we observed this is: In case you need to support any new or other existing HTTP server frameworks you will need to create a type and recompile the framework. Curious ones who are interested to explore the ways these known types are created should explore the current implementation in github[2] repo of the nest framework. Let us mark this as a topic for some other Oblog.

To production & beyond

While wrapping up this dispatch I want to quiz ourselves with – Why should we create a HTTP server in the entry method? Is this not the responsibility of HTTP server e.g. HTTPD from Apache and Nginx etc. Isn’t this how we used to program with traditional programming languages?

It took me a while to reason myself with this question and to discover the reason as well. Answer is a paradigm shift to developers from the traditional grounds. You will have the “Aaha” moment when you start looking at HTTP server as a component instead of a container which contains the deployed code. Take a while; re-read the previous sentence.

Again, HTTP server is a component of the application you are developing it is not a container where you will deploy your code.

Having digested that fact, there are few options in the production environment to scale up and be robust for varying loads. PM2 is the node deamonizer which helps you convert a nestjs HTTP service to a deployed application. You could front-end it with Nginx proxy, load balance it, containerize it or even use Platform as a Service of popular cloud vendors e.g. Azure and AWS. Details on this topic is for some other dispatch.

Till next time, keep puzzling yourself as it indicates progress!!

 

[4] Fastify framework – https://www.fastify.io/

[5] GitHub folder in nestjs project for Express JS implementation – https://bit.ly/2X46Wyu