Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I tried nestjs but I realized it reduces code readability because of so many decorators, please take a second to visit this

Tags:

node.js

nestjs

I recently used nestjs, But I realized its overcomplicated, I mean look the following code:

@post('/products')
getAllProducts(@Body('title') title, @Body('price') price, @Body('description') description) { }

It makes function parameters much dirty, Also there could be more decorators above function like @Header, @Params, etc.. Which reduces readability in my opinion. Same code in nodejs

const { title: title, price: price, description: description } = req.body

nodejs is much more readable...

Then I researched why developers use nestjs, Reason was Modularity. Why we don't implement this on our own...

See below:

See my directory sutructure

In app.js I just kicked the app:

const express = require('express');

const app = express();

// express config
require('./startup/config')(app);

// handling routes
require('./startup/routes')(app);

// db setup
require('./startup/db')(app);

In startup folder I did the basic work like mongoose configuration and connection to db etc..

However, In startup/routes, I just kicked the module as follow:

const shopModule = require('../shop/shop.module');

module.exports = app => {
    app.use('/', shopModule);
};

In shop module, I just kicked the routes as follow:

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

const productsRouter = require('./products/index');
const cartRouter = require('./cart/index');

// Products
router.use('/products', productsRouter)
// Cart
router.use('/cart', cartRouter)

module.exports = router;

Now in cart/index.js, I handled the routes related to cart and same for products as follow (I will just show cart):

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

const { getCart } = require('./cart.controller');

router.get('/', getCart);

module.exports = router;

In controller, basically we will do validation stuff etc or extracting data.. Then controller will kick service for database work..

const { userCart } = require('./cart.service');

exports.getCart = (req, res, next) => {
    const cart = userCart();
    return res.status(200).json(cart);
};

And finally in cart service:

exports.userCart = _ => {
    // ... go to database and fetch cart
    return [{ prodId: 123, quantity: 2 }];
};

And cart.model.js is responsible for DB schema,

I know the question was too long, but I wanted to explain my question.

I am not saying nestjs should not be used, I am just saying, what about the following structure as it follows the same pattern as angular or nestjs, Right?

like image 761
asdsad Avatar asked Sep 11 '19 11:09

asdsad


People also ask

What are the decorators in NestJS?

An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an @ character and placing this at the very top of what you are trying to decorate.

How do NestJS decorators work?

A decorator is an expression that returns a function. It can take a target, name and property descriptor as arguments. We apply a decorator with an @ character and place it at the top of what we are trying to decorate. We can define decorators for class, method or a property. NestJS provides a set of param decorators.

Is NestJS a good choice?

Nestjs gives a very clean structure for building web apps. It can be compared to well established frameworks like LARAVEL, DJANGO in case of functionalities. yes it may not be as popular but it is growing. I really recommend using nestjs.

Which companies are using NestJS?

Who uses NestJS? Some of the most notable companies that use Nest JS to build efficient and scalable server-side applications are Autodesk, Societe Generale, Gojob, Adidas, Decathlon, Rewe Digital, and many others.


2 Answers

it's dirty because you write it in the wrong way

why not use it like this

@Get('/')
getAllProducts(@Body() product: Product) {}

and then destructure it

const {title, price, description} = product
like image 127
Phan Văn Tiến Avatar answered Sep 19 '22 13:09

Phan Văn Tiến


With your first point about making the code more readable, why not do something like

@Post('/products')
getAllProducts(@Body() body: any) {}

instead of calling for each part of the body individually, then you can deconstruct the body as you showed with

const {title: title, price: price, description: description} = body;

No need to specify each part of the body that you need as a new parameter, just grab the object itself. The same also goes for @Header(), @Param(), and @Query().

As for how you are setting up your express app, you are completely correct that you can do that; however, if you are working on an open source project, or collaborating with other developers there is nothing that says they have to follow the same format and it could eventually lead to a messy code base. Nest enforces these patterns, similar to how Angular does. Sure, it is still possible to write terrible code, but with an opinionated architecture it does make it more difficult.

NestJS also treats Typescript as a first class citizen, which in my opinion helps get rid of a lot of development problems as well. Plus you get some really cool packages to play with like class-validator and class-transformer to help with validation and transformation of your requests via pipes. You can write an Express server in Typescript, but it isn't necessary, and you can write a NestJS server in JavaScript, but I think you lose a lot of good functionality if you do.

The last point that I don't think has been touched too much it that Nest handles a lot of black boxing for your code through it's modules. If you define a service for a module, it is only available for that module. If you need it in another module you have options, but it helps cut down on the cross-contamination of code and keeps a separations of concerns ideology in mind.

In my opinion, the fact the NestJS gives us specified files for things like authentication (guards), validation and transformation (pipes and interceptors), and error handling (exception filters) makes it easier for anyone to pick up a NestJS server and have a quick understanding of how the request will flow through the server, even if by just looking at the file structure. Personally I know if I see an AuthModule or a guards folder I'm going to be dealing with authentication to some extent.

To answer your final question: there is nothing wrong with how you are showing the express example, especially as you are using Inversion of Control by passing the app into the router to make it work that way, you can absolutely write an Express server that way. Nest just makes you do it that way. (I mean, you could write an entire server using just AppController, AppService and AppModule, but that's really an anti-pattern)

In the end, definitely use what you're comfortable with, but there is a reason Nest has become so popular recently.

like image 33
Jay McDoniel Avatar answered Sep 22 '22 13:09

Jay McDoniel