This article highlights the six most important tips I have learned by analyzing my previous projects from the last few years. In it, I have compiled a list of recommendations to help in facilitating the development process of node.js apps. There aren't only six tips, of course, I've only listed the six most important ones according to my experience.
TypeScript extends JavaScript by adding types to it. It saves you time by catching errors and providing fixes before you run code. It may seem that using TypeScript will increase development time, but you will spend more time on debugging unless you go with TypeScript.
You can take advantage of these benefits when using TypeScript:
Note: Avoid using the "type any" option because this renders using TypeScript meaningless.
It's important to have a good error handler to notice and fix all possible errors. Your app should have a unified structure of the error object that will include all the necessary data related to the error.
One of the solutions for this is to have a base error class, that will extend node.js native error class, and will include all the properties and methods you need. Afterward, it's necessary to create error classes for possible types of errors by extending BaseError class. In the diagram below, you can see an example of such a hierarchy, where for each http response code there is a defined separate error class.
One of the solutions for this is to have a base error class, that will extend node.js native error class, and will include all the properties and methods you need. Afterward, it's necessary to create error classes for possible types of errors by extending BaseError class. In the diagram below, you can see an example of such a hierarchy, where for each http response code there is a defined separate error class.
Here are the code examples of implementation for such classes:
After having these classes, whenever you want to throw an error, you need to use instances of them.
Also, it's required to have an error handler function that can understand error types and do appropriate action based on it. As an example, let's look at the following error handler which is an express middleware. It responds with either current or an internal error object, based on error instances.
It's very inconvenient to maintain current modern applications without having docker integrated. Docker solves lots of things related to application scaling, deployment and more.
Here are some of the benefits you will get if you integrate docker into your apps:
Be it unit tests, integration tests or whatever else, it's great to have automation tests implemented. Automation tests are your reliable friends during hard times. There are lots of cases that cover automation tests, but I'm going to describe it from the point of view of a developer.
My suggestion is to set up and start implementing tests from the first day of the project. Previously, I was of the opinion that automation tests are not important and was classifying them as secondary jobs. Now, I understand that it's one of the best things to protect you from yourself.
Everybody knows how productive people are when they start working but how tired they get at the end of the working day. When you are tired, you can make simple mistakes, because of this later on you will spend a lot of time debugging and finding issues. Usually, we finish our tasks by the end of the working day but by then we are too tired to test manually all the related functionality.
By having automation tests implemented, you can run tests every time after adding a new feature or when anything in the code is changed. It's a great way to make sure that everything is working correctly and other functionalities are not affected after changes. Even if something was broken and tests are failing, you can easily find the problem and fix it.
I know it's hard to make yourself write tests each time after adding new features or making changes in the code, but it is the best way to protect yourself from the tired version of you.
Another thing that facilitates your work is CI/CD set up. This will let you stay away from the server command line and will reduce time spent on deployments.
My suggestion is to set up CI/CD for all the environments (testing, staging, prod, etc.) you have. Run all kinds of tests you have each time something is being pushed to the git repository. Setup specific git branches or tags for making automatic deployment.
Another benefit of it is auto-generated environment variable files (.env). Usually, CI/CD platforms have the possibility to keep secrets like database password, API Key, etc. For example, CircleCI has a section called Contexts which is for keeping environment variables and secrets, Pipelines of Azure have secret files for the same purpose and so on...
I can't think of any application that doesn't receive and process external data. All applications have input data, be it Rest API, daemon service or any other. A good data validator is required to ensure the smooth operation of your service.
As an example let's take a Rest API app. The app receives some data from clients, processes it and responds with appropriate response data. In the Rest API case, clients can pass data to endpoints in various ways (query, body, headers, etc..) and it's important for the app to process the request data only if it is correct.
There are various libraries which can cover this problem and one of them is joi. It's an awesome library with lots of functionality.
The diagram above shows the validation mechanism of the Rest API app using JOI as a middleware. The middleware receives data from clients, validates it, corrects it in some cases and, afterward passes it to the next middleware. In case of incorrect data, it throws validation errors.
The tips I shared with you are just things that I understood from my own experience and I'm sure that they are not ideal solutions for everyone. After all, each project has its own requirements, even solutions different from the standard. Hopefully, this article will help you to facilitate the development process and free up time for other things.