Deno再尝试:使用Deno编写一个简单的WebAPI

💡 原文中文,约4500字,阅读约需11分钟。
📝

内容提要

作者两年前尝试过Deno,如今再次使用Deno构建活动监测器。文章介绍了Deno.serve处理请求、手动路由、统一响应格式、Deno KV存储数据,以及用Rust编写客户端上报状态,并通过macOS launchd后台运行。最终部署到Deno Deploy,作者认为Deno已成熟,适合小工具和个人项目,但大型生产项目仍需谨慎。

🔎

延伸解读

Deno 的模块系统演进

文章提到 Deno 最初采用基于 HTTP 的模块导入,长 URL 使代码杂乱且依赖管理困难。如今 Deno 支持更易用的导入方式,这反映了其生态的成熟。对于开发者而言,这意味着 Deno 在依赖管理上正在向传统 npm 模式靠拢,降低了上手门槛,但具体支持方式(如 npm 兼容或 import maps)需查阅官方文档。

手动路由的适用场景

作者未使用 Web 框架,而是通过解析 pathname 手动实现路由,并用 Map 封装处理函数。这种方式适合接口数量少的小项目,代码简洁且无额外依赖。但对于路由复杂、需要中间件或参数解析的场景,手动路由会变得繁琐,此时引入框架(如 Hono 或 Oak)可能更高效。

Deno KV 的本地与云端差异

Deno KV 在 Deno Deploy 上可直接使用,但本地运行需启用 --unstable-kv 实验特性。这意味着本地开发与云端部署存在环境差异,开发者需注意配置。此外,Deno KV 的键数组设计支持层级组织和范围查询,适合简单持久化需求,但相比传统数据库,其功能可能有限,不适合复杂查询。

launchd 环境变量注意事项

macOS 的 launchd 服务不直接读取 Shell 环境变量,需通过 launchctl setenv 设置。作者在部署 Rust 客户端时遇到此问题,并提供了解决方案。这提醒开发者,在将程序作为后台服务运行时,需显式配置环境变量,否则程序可能因缺少配置而运行失败。

Q&A

Deno.serve 的基本用法是什么?

Deno.serve 接受一个处理函数,该函数接收 Request 对象并返回 Response。例如:const handler = (req) => new Response('Hello'); Deno.serve(handler);

Deno 如何实现路由?

Deno 本身没有内置路由系统,但可以通过解析 URL 的 pathname 手动实现。简单场景下用 if 判断,复杂一点可以将处理函数封装到 Map 或对象中,根据 pathname 匹配调用。

如何统一 Deno Web API 的响应格式?

可以封装一个响应类,统一管理 success、message、data 等字段,并提供 json() 方法返回 JSON 响应,同时设置 CORS 头。这样所有接口都返回统一格式。

Deno KV 是什么?如何使用?

Deno KV 是 Deno 内置的键值存储,可用于持久化数据。使用 Deno.openKv() 打开,通过 kv.set() 和 kv.get() 操作,键为数组,支持层级和范围查询。本地使用需启用 --unstable-kv 实验特性。

如何用 Rust 编写一个定时上报状态的客户端?

使用 Rust 的 tokio 和 reqwest 库,每隔一定时间(如 20 分钟)向指定 API 发送 GET 请求,携带 apikey 头。示例代码中使用了 tokio::time::interval 和 reqwest::Client。

如何将程序作为 macOS 后台服务运行?

使用 launchd 创建 plist 文件,设置 Label、ProgramArguments、RunAtLoad 和 KeepAlive。注意 launchd 不读取 shell 环境变量,需用 launchctl setenv 设置。这样程序异常退出后会被自动拉起。

Deno Deploy 有哪些特点?适合什么场景?

Deno Deploy 提供 Deno 程序部署、KV 存储、定时任务等能力,部署流程简单,速度快。适合小工具、小型 Web API 或个人项目,可以免维护服务器。

作者对 Deno 的总体评价是什么?

作者认为 Deno 相比两年前已成熟不少,标准库完善,开发体验提升。虽然不适合大型生产项目,但对于小工具、小型 Web API 或个人项目已经足够好用,尤其配合 Deno Deploy 和 Deno KV 很方便。

🏷️

标签

➡️

继续阅读