我如何构建我的 REST API
这篇文章最初发表在我的博客上。
当我开始使用Node.js在服务器端构建 REST API 时,我一次又一次地被同样的问题困扰:
文件夹结构应该是什么样的?
显然,这个问题没有完美或 100% 正确的答案,但在阅读了一些相关的文章后,我找到了一个非常符合我需求的文件夹结构和架构。所以今天我想向大家展示我是如何构建和组织我的 Node.js REST API 的。
我还发布了一个 GitHub存储库,其中包含一个示例应用程序,您可以将其用作您自己项目的模板。
需要说明的是,我使用Express.js作为 Web 框架,并使用TypeORM作为 ORM。将此文件夹结构应用于其他框架应该也不难。
该架构主要基于组件,这使得我们能够更轻松地只请求真正需要的数据。例如,我们有一个User
包含所有用户信息的组件。
让我们从root
目录开始。
目录:根目录
expressjs-api
└───db
│
└───dist
│
└───logs
│
└───node_modules
│
└───src
│
│ README.md
│ ...
src
这个结构没什么特别的,对你来说应该不陌生。它实际上是一个基本的 Node.js 设置。这里有趣的部分是这篇文章所讨论的文件夹的内容。
那么我们这里有什么?
expressjs-api
└───src
│
└───api
│ │
│ └───components
│ │
│ └───middleware
│ │
│ │ routes.ts
│ │ server.ts
│
└───config
│
└───services
│
└───test
|
│ app.ts
从这里开始,我们将自上而下地逐一介绍文件/目录,并逐一进行解释。首先从api
目录开始,它是应用程序最重要的部分。
目录:src/api/components
expressjs-api
└───src
│
└───api
│
└───components
│
└───article
│
└───auth
│
└───country
│
└───user
│ helper.ts
│ index.ts
这里我们可以看到基于组件的 Node API 的核心。每个组件都有自己的路由、控制器、模型、存储库、策略、测试和模板。
让我们进入User
组件看看吧。
目录:src/api/components/user
expressjs-api
└───src
│
└───api
│
└───components
│
└───user
│
└───services
| │ mail.ts
└───templates
| │ confirmation.html
| | invitation.html
│ controller.ts
│ model.ts
│ policy.json
│ repository.ts
│ routes.ts
│ user.spec.ts
如你所见,组件由我之前提到的文件组成。它们大多数代表一个导出的类。当然,你可以在这里添加更多组件特定的内容。
由于我有多个组件,并且它们的类大多数情况下具有相同的结构,因此我还创建了在类中实现的接口。这有助于我保持组件结构的一致性。
此外,我们services
这里的目录包括本地组件服务mail
,例如来自全局服务的交互服务。
该templates
目录包含指定组件的邮件 HTML 模板。对于动态渲染 HTML 代码,我强烈推荐ejs。
控制器.ts
控制器类处理传入的请求并将响应数据发送回客户端。它使用该类repository
与数据库进行交互。请求验证通过中间件在执行前几步进行。
一个简短的例子:
export class UserController {
private readonly repo: UserRepository = new UserRepository()
async readUser(
req: Request,
res: Response,
next: NextFunction
): Promise<Response | void> {
try {
const { userID } = req.params
const user: User | undefined = await this.repo.read({
where: {
id: +userID,
},
})
return res.json(user)
} catch (err) {
return next(err)
}
}
}
模型.ts
该模型代表其组件的数据库模型。在我的例子中,它是一个TypeORM类。它主要由类使用repository
。
策略.json
此 json 文件包含每个用户角色对指定组件的访问权限。它是基于访问控制列表系统的一部分。
例子:
{
"Admin": [{ "resources": "user", "permissions": "*" }],
"User": [{ "resources": "user", "permissions": ["read"] }]
}
存储库.ts
存储库类就像数据库的包装器。在这里,我们可以读写数据库中的数据。此外,我们还可以实现缓存等功能。
您可以将该repository
类导入到任何其他文件中,并从数据库中查询该组件的数据。此外,由于我们不必多次重写 SQL 语句,因此它可以避免编写冗余代码。
由于大多数组件存储库都需要相同的基本访问方法,例如readAll
、和read
,save
因此delete
我使用了一个包含所有这些方法的通用父类。这节省了大量代码。
请参阅AbsRepository了解具体实现。
路线.ts
这里我们定义了相应组件的API端点controller
,并为其分配方法。此外,我们还可以添加更多内容,例如
- 授权(例如 JWT)
- 权限检查(ACL)
- 请求主体验证
- 组件特定的中间件在这里。
简短的例子:
class UserRoutes implements IComponentRoutes<UserController> {
readonly name: string = "user"
readonly controller: UserController = new UserController()
readonly router: Router = Router()
authSerivce: AuthService
constructor(defaultStrategy?: PassportStrategy) {
this.authSerivce = new AuthService(defaultStrategy)
this.initRoutes()
}
initRoutes(): void {
this.router.get(
"/:userID",
this.authSerivce.isAuthorized(),
this.authSerivce.hasPermission(this.name, "read"),
param("userID").isNumeric(),
this.authSerivce.validateRequest,
this.controller.readUser
)
}
}
用户规范.ts
这是用于测试组件及其端点的测试文件。您可以在此处阅读有关测试此架构的更多信息。
目录:src/api/middleware/
expressjs-api
└───src
│
└───api
│
└───middleware
│ compression.ts
│ loggin.ts
此文件夹包含所有 API 的全局中间件,如压缩、请求日志等。
文件:src/api/routes.ts
expressjs-api
└───src
│
└───api
│ routes.ts
server
这里我们注册了所有组件和中间件的路由。这些路由稍后会在类中使用。
文件:src/api/server.ts
expressjs-api
└───src
│
└───api
│ server.ts
这里我们声明了 Express.js 服务器所需的一切:
- 导入中间件
- 导入路线
- 错误处理
稍后,我们server
也可以导入该类进行单元测试。
目录:src/config
expressjs-api
└───src
│
└───config
│ globals.ts
│ logger.ts
│ permissions.ts
此目录包含 API 的配置文件。例如:
- 全局变量
- 记录器配置
- ACL权限
- SMTP 配置
请随意将任何与配置相关的文件放在这里。
目录:src/services/
该目录包含我们可能需要的全局服务,例如授权、发送邮件、缓存或辅助方法。
expressjs-api
└───src
│
└───services
│ auth.ts
│ helper.ts
│ mail.ts
| redis.ts
授权.ts
在这里,我们设置应用程序的护照策略等内容并定义授权方法。
助手.ts
辅助类包含用于散列、UUID等的辅助方法。
邮件.ts
该服务用于发送邮件和渲染组件的模板。再次推荐ejsrenderFile
的功能。
目录:src/test/
此目录包含用于运行组件测试的测试工厂。您可以在此处
阅读更多相关信息。
文件:src/app.ts
这是我们应用程序的启动文件。它初始化数据库连接并启动 Express 服务器。
expressjs-api
└───src
│ app.ts
全部在一起
最后但同样重要的是项目结构的完整概述:
expressjs-api
└───src
│
└───config
│ │ globals.ts
│ │ logger.ts
│ │ permissions.ts
│
└───api
│ │
│ └───components
│ │ │
│ │ └───article
│ │ │
│ │ └───user
| │ │ │
| │ │ └───templates
| │ │ | │ confirmation.html
| │ │ | │ invitation.html
│ │ | │ controller.ts
│ │ | │ model.ts
│ │ | │ policy.json
│ │ | │ repository.ts
│ │ | │ routes.ts
│ │ | │ user.spec.ts
│ │
│ └───middleware
│ │ │ compression.ts
│ │ │ logging.ts
│ │
│ │ routes.ts
│ │ server.ts
│
└───services
│
└───test
|
│ app.ts
就是这样!希望这能给那些不知道如何构建 Node.js 应用程序或不知如何入门的人一些帮助。我认为还有很多事情可以做得更好或更高效。
如果您有兴趣为 Node.js REST API 编写单元测试,请查看这篇涵盖相同架构的文章。
我还发布了一个包含示例应用程序的 GitHub 仓库。可以看看。
文章来源:https://dev.to/larswaechter/how-i-struct-my-rest-apis-11k4