本文介绍了我尝试过 nestjs,但我意识到它因为有太多装饰器而降低了代码的可读性,请花点时间访问这个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近使用了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) { }

它使函数参数变得很脏,而且函数上面可能有更多的装饰器,如@Header、@Params 等.在我看来,这降低了可读性.nodejs中的相同代码

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 更具可读性...

nodejs is much more readable...

然后我研究了为什么开发人员使用 nestjs,原因是模块化.为什么我们不自己实现这个...

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

见下文:

查看我的目录结构

在 app.js 中,我刚刚踢了应用程序:

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);

在启动文件夹中,我做了一些基本的工作,比如 mongoose 配置和连接到数据库等.

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;

现在在cart/index.js中,我处理了与cart相关的路由,对于产品也一样(我只会显示cart):

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);
};

最后在购物车服务中:

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

而cart.model.js负责DB schema,

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

我知道这个问题太长了,但我想解释一下我的问题.

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

我不是说不应该使用 nestjs,我只是说,下面的结构怎么样,因为它遵循与 angular 或 nestjs 相同的模式,对吗?

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?

推荐答案

关于使代码更具可读性的第一点,为什么不做类似的事情

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;

无需将身体的每个部分都指定为新参数,只需抓取对象本身即可.@Header()@Param()@Query() 也是如此.

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().

至于您如何设置 Express 应用程序,您可以这样做是完全正确的;但是,如果您正在从事开源项目,或者与其他开发人员合作,则没有任何内容表明他们必须遵循相同的格式,并且最终可能会导致代码库混乱.Nest 强制执行这些模式,类似于 Angular 的做法.当然,编写糟糕的代码仍然是可能的,但如果采用固执己见的架构,确实会增加难度.

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 也将 Typescript 视为一等公民,这在我看来也有助于摆脱很多开发问题.此外,您还可以使用一些非常酷的包,例如 class-validatorclass-transformer 来帮助通过管道验证和转换您的请求.你可以用 Typescript 写一个 Express 服务器,但这不是必需的,你用 JavaScript 写一个 NestJS 服务器,但我认为你失去了很多好的功能如果你这样做.

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.

最后一点,我认为没有被触及太多,Nest 通过它的模块为你的代码处理了很多黑盒.如果您为某个模块定义服务,则它仅可用于该模块.如果您在另一个模块中需要它,您可以选择,但它有助于减少代码的交叉污染,并牢记关注点分离的思想.

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.

在我看来,NestJS 为我们提供了用于身份验证(保护)、验证和转换(管道和拦截器)以及错误处理(异常过滤器)等指定文件的事实使任何人都可以更轻松地使用 NestJS 服务器并快速了解请求将如何流经服务器,即使只是查看文件结构.我个人知道如果我看到 AuthModuleguards 文件夹,我将在某种程度上处理身份验证.

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.

回答你的最后一个问题:你展示的例子没有任何问题,特别是当你通过将 app 传递到路由器来使用控制反转以使其以这种方式工作时,您绝对可以通过这种方式编写 Express 服务器.Nest 只是你这样做.(我的意思是,您可以仅使用 AppControllerAppServiceAppModule 来编写整个服务器,但这确实是一种反模式)

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)

最后,一定要使用您喜欢的东西,但 Nest 最近变得如此受欢迎是有原因的.

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

这篇关于我尝试过 nestjs,但我意识到它因为有太多装饰器而降低了代码的可读性,请花点时间访问这个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 02:18