有很多非常好的教程适合任何想要使用TypeScript和Express构建 REST API的人。但是,这些教程有两个缺点:
它们要求你安装和配置TypeScript,并且需要安装一切所需的内容。这可能很耗时,对于新开发人员来说可能会增加他们的挫败感。
它们没有解决不受信任的代码的需要。这并不奇怪,因为大多数工具都不支持它。
这就是为什么我们创建了这个教程。使用Deno,您无需配置TypeScript,因此可以最小化依赖关系并立即运行。
Deno是一款基于V8引擎和Rust语言构建的新一代JavaScript和TypeScript运行时环境,由Node.js的创始人之一Ryan Dahl开发。与Node.js不同的是,Deno具有更好的安全性和模块化系统,同时也提供了更好的开发体验。
Deno的主要特点包括:
安全性:Deno默认禁止文件访问、网络访问和环境变量等敏感操作,需要显式的权限授予才能进行。
模块化:Deno的模块系统使用ES模块标准,支持URL导入和自动缓存模块等特性。
支持TypeScript:Deno原生支持TypeScript,无需安装任何其他插件或工具。
内置工具:Deno内置了许多有用的工具,如格式化代码、代码测试、代码覆盖率等。
如何安装,这里就不过多介绍了,感兴趣的话可以去官网查看:
https://deno.land/
1、首先在你的项目文件夹里,使用 deno init 命令初始化你的项目,初始化成功如下图所示的文件结构:
2、接下来我们修改 main.ts 文件,让其包含我们 API 的逻辑
import express, { NextFunction, Request, Response } from "npm:[email protected]";
3、接下来,我们需要定义一种与 Express 的应用程序界面交互的方式,我们将需要定义一个端口供其运行,我们将从环境中获取该端口:
const app = express();
const port = Number(Deno.env.get("PORT")) || 3000;
4、让我们定义一个测试路由,它会在收到 GET 请求时,会输出“Hello from Deno and Express!”,我们现在将其设为默认基本路由:
app.get("/", (_req, res) => {
res.status(200).send("Hello from Deno and Express!");
});
5、现在我们已经构建了简单的逻辑,我们只需要它来监听并开始服务请求!为此,我们将使用 .listen(),如下所示:
app.listen(port, () => {
console.log(`Listening on ${port} ...`);
});
1、让我们启动我们的服务器,使用 deno run ./main.ts
2、此时,我们已经拥有一个正在运行的API服务,我们可以使用curl进行查询:
3、我们现在确定框架正常工作,因此我们对安装和其他所有事情都很有把握。但是,它还不是一个很好的工作环境,因此让我们设置我们的deno.jsonc文件来定义一些辅助脚本:
这类似于 package.json 脚本(实际上,Deno 甚至可以使用 package.json 脚本,但建议使用 deno.jsonc),其中我们有一个任务用于开发,另一个任务用于启动服务器而不会在更改时进行监视和重载。
通过查看 deno task 的输出,我们可以确认我们有两个可用的脚本:
$ deno task
Available tasks:
- dev
deno run --allow-read --allow-net --allow-env --watch main.ts
- start
deno run --allow-read --allow-net --allow-env main.ts
我们可以分别使用 deno task dev 和 deno task start。
接下来我们需要一些日志记录功能,以便在构建请求时进行故障排除,这是介绍 Express 中间件概念的好机会。
中间件是一个可以读取和修改 req 和 res 对象的函数。我们使用中间件来做从日志记录到注入头部,甚至限流和检查身份验证的所有事情。中间件完成时必须执行以下两项操作之一:
如果合适,它必须使用响应关闭连接,或者
它必须调用 next(),这告诉 Express 该将对象传递给下一个中间件函数
中间件有三个参数:req 和 res,正如您所预期的那样,还有 next,它指向下一个适当的中间件函数(或将控制返回给处理程序函数)。
让我们定义第一个中间件函数作为记录日志,而不是在每个处理程序中写入 console.log(),并告诉 Express 我们想要使用它。在 main.ts 文件中:
const reqLogger = function (req, _res, next) {
console.info(`${req.method} request to "${req.url}" by ${req.hostname}`);
next();
};
你可以有尽可能多的中间件,并以适合你的方式进行组织。但要记住,你的响应速度取决于你的中间件链有多快地将控制权交回框架。中间件按照框架被告知的顺序执行。
1、新建 generate_data.ts 测试数据文件,示例代码如下:
const fakeDate ={
users:[
{
id:1,
name:"前端达人",
department:"前端体验部"
},
{
id:2,
name:"设计达人",
department:"前端体验部"
},
{
id:3,
name:"后端达人",
department:"后端研发部"
}
]
}
await Deno.writeTextFile(
"./data_blob.json",
JSON.stringify(fakeDate,null,2)
)
2、运行./generate_data.ts命令(如果提示没有权限,则运行deno run -A ./generate_data.ts),这将在data_blob.json中生成一些虚拟用户数据,运行成功后,你的项目文件里会有一个 data_blob.json 文件,示例如下:
{
"users": [
{
"id": 1,
"name": "前端达人",
"department": "前端体验部"
},
{
"id": 2,
"name": "设计达人",
"department": "前端体验部"
},
{
"id": 3,
"name": "后端达人",
"department": "后端研发部"
}
]
}
3、我们可以通过Deno的导入类型断言安全地使用它,就像任何其他只读数据存储一样。
import demoData from "./data_blob.json" assert { type: "json" };
4、现在我们的处理程序可以访问 demoData.users,因此让我们编写两个处理方法:
/users,返回所有用户对象的内容
另一个处理程序是动态路由,允许我们通过ID查找单个用户
app.get("/users", (_req, res) => {
res.status(200).json(demoData.users);
});
app.get("/users/:id", (req, res) => {
const idx = Number(req.params.id);
for (const user of demoData.users) {
if (user.id === idx) {
res.status(200).json(user);
}
}
res.status(400).json({ msg: "User not found" });
});
5、我们也可以删掉默认的hello world路由,最后完整的代码内容如下:
// @deno-types="npm:@types/express@4"
import express, { NextFunction, Request, Response } from "npm:[email protected]";
import demoData from "./data_blob.json" assert { type: "json" };
const app = express();
const port = Number(Deno.env.get("PORT")) || 3000;
const reqLogger = function (req, _res, next) {
console.info(`${req.method} request to "${req.url}" by ${req.hostname}`);
next();
};
app.use(reqLogger);
app.get("/users", (_req, res) => {
res.status(200).json(demoData.users);
});
app.get("/users/:id", (req, res) => {
const idx = Number(req.params.id);
for (const user of demoData.users) {
if (user.id === idx) {
res.status(200).json(user);
}
}
res.status(400).json({ msg: "User not found" });
});
app.listen(port, () => {
console.log(`Listening on ${port} ...`);
});
接下来,我们请求下用户接口试试,如下图所示:
本文详细介绍了如何使用Deno,Express和TypeScript构建REST API。如果您是新手或者希望在不浪费时间的情况下快速入门,那么本教程将为您提供所需的一切。与其他教程不同,本教程无需安装和配置TypeScript,因此可以最小化依赖关系并立即运行。
总之,本文提供了一个简单而有效的方法来构建REST API,而且没有过多的依赖关系,从而使您能够立即开始编码。
文章创作不易,如果你喜欢我的分享,别忘了点赞转发,让更多有需要的人看到,最后别忘记关注「前端达人」,你的支持将是我分享最大的动力,后续我会持续输出更多内容,敬请期待。
原文:
https://deno.com/blog/build-api-express-typescript作者:Tim Post
非直接翻译,有自行改编和添加部分,翻译水平有限,难免有疏漏,欢迎指正