文章目录
- 一、核心基础:面向对象中的接口(Interface)
-
- 1.1 接口的核心定义
- 1.2 面向对象三大特性与接口的关系
- 1.3 接口与抽象类的核心区别
- 1.4 接口的核心价值
- 二、行业规范:RESTful 接口设计思想
-
- 2.1 RESTful 核心理念:一切皆资源
- 2.2 RESTful 核心设计规则
-
- 2.2.1 资源命名规则
- 2.2.2 HTTP 动词语义对应
- 2.2.3 路由的核心作用
- 三、实战落地:Bun+TS 实现 RESTful TodoList 服务端
-
- 3.1 步骤1:通过接口约束 Todo 数据结构
- 3.2 步骤2:启动 Bun HTTP 服务 & 实现路由匹配
- 四、前端实战:页面请求渲染 Todo 列表
- 五、全文总结
- 六、核心知识点复盘
- 七、常见问题 & 避坑指南
在前后端开发入门阶段,RESTful 接口设计和面向接口编程是两大核心基础能力。绝大多数业务系统(任务管理、用户中心、订单系统)的接口设计,都遵循 RESTful 规范,而接口(Interface)是支撑整个设计模式的底层思想。
本文将通过 Bun + TypeScript 从零手写 TodoList 任务清单接口,从底层概念、核心原理、代码实战到避坑总结,完整讲解面向接口编程和 RESTful 接口设计,兼顾新手入门和技术复盘,所有代码可直接运行、可落地复用。
一、核心基础:面向对象中的接口(Interface)
1.1 接口的核心定义
接口是面向对象编程(OOP)的核心抽象概念,区别于类的具象实现,接口只负责定义约束、不实现逻辑。简单来说:接口就是一套「规则契约」,规定某个对象必须具备哪些属性、哪些方法,不关心具体实现方式。
在 TypeScript 中,接口是自定义类型的核心载体,弥补了 JavaScript 弱类型的短板,让对象结构可约束、可校验、可统一规范。
1.2 面向对象三大特性与接口的关系
面向对象的封装、继承、多态三大特性,都可以通过接口落地实现,这也是接口是「设计模式基础」的核心原因:
- 封装:接口对外隐藏内部实现细节,只暴露规范的属性和方法,使用者只需遵守规则,无需关心底层逻辑。
- 继承:接口可被拓展、叠加,子接口可以继承父接口的约束,实现规则的复用。
- 多态:多个不同的对象,只要实现同一个接口,就可以统一被接口类型接收,适配不同场景。
1.3 接口与抽象类的核心区别
很多新手会混淆接口和抽象类,这里做通俗区分:
- 抽象类:可以包含具体属性、已实现方法、抽象方法,是「半抽象、半具象」的模板,偏向于事物共性的模板定义。
- 接口:只能定义属性和方法的声明,无任何具体实现,是「纯抽象规则」,偏向于行为、结构的约束定义。
核心强制规则:所有实现接口的类/对象,必须完整实现接口声明的所有属性和方法,缺一不可,否则会触发类型校验错误。
1.4 接口的核心价值
面向对象编程是代码落地的基础,而面向接口编程是工程化设计模式的基础。通过接口可以实现:
二、行业规范:RESTful 接口设计思想
2.1 RESTful 核心理念:一切皆资源
RESTful 是目前行业通用的接口设计规范,其最核心的思想是 一切皆资源。系统中所有可操作的内容(任务、用户、订单、文章)都是独立资源。
RESTful 摒弃了传统接口「路径+方法名」的混乱设计,通过 URL 定位资源 + HTTP 动词描述操作 的语义化方式定义接口,让接口路径清晰、语义统一、可读性极强。
2.2 RESTful 核心设计规则
2.2.1 资源命名规则
URL 中只使用名词复数表示资源,禁止使用动词,所有操作通过 HTTP 动词区分。
错误示例:/getTodoList、/addTodo(路径包含动词,不符合规范) 正确示例:/todos(任务资源)、/users(用户资源)
2.2.2 HTTP 动词语义对应
通过标准 HTTP 动词,定义对资源的增删改查操作,语义完全对齐:
| GET | 查询资源 | 获取任务列表、获取单个任务详情 |
| POST | 新增资源 | 创建新的任务 |
| PUT | 全量更新资源 | 完整修改任务信息 |
| PATCH | 局部更新资源 | 仅修改任务完成状态 |
| DELETE | 删除资源 | 删除指定任务 |
2.2.3 路由的核心作用
路由可以理解为服务器的「交通警察」,负责拦截客户端请求、匹配请求路径和请求方法、分发对应处理逻辑。不同的资源对应不同的 URL 路径,同一资源的不同操作通过 HTTP 动词区分,这就是 RESTful 路由的核心逻辑。
三、实战落地:Bun+TS 实现 RESTful TodoList 服务端
本次实战基于 Bun 高性能服务端 runtime + TypeScript 强类型约束 实现,无需额外搭建 Express/Koa 框架,原生 Bun 即可快速启动 HTTP 服务,代码轻量化、运行效率更高。
3.1 步骤1:通过接口约束 Todo 数据结构
基于面向接口编程思想,先定义 Todo 接口,约束任务对象的所有字段结构,实现数据规范化,从根源避免数据格式混乱。
// 定义Todo任务接口:约束任务对象的结构(核心契约)
interface Todo {
id: string; // 任务唯一标识
title: string; // 任务标题
completed: boolean;// 任务完成状态
createdAt: Date; // 任务创建时间
}
// 基于Todo接口,初始化模拟任务数据
const todos: Todo[] = [
{
id: '1',
title: '吃饭',
completed: false,
createdAt: new Date()
},
{
id: '2',
title: '睡觉',
completed: false,
createdAt: new Date()
},
{
id: '3',
title: '打豆豆',
completed: false,
createdAt: new Date()
},
];
代码核心解析:
- 接口 Todo 定义了任务对象的必填属性和对应类型,所有任务数据必须遵守该结构;
- todos: Todo[] 约束数组内所有元素都必须是 Todo 类型,实现强类型校验;
- 完全体现面向接口编程思想:先定义规则,再落地数据。
3.2 步骤2:启动 Bun HTTP 服务 & 实现路由匹配
使用 Bun 原生 serve 方法启动高性能 HTTP 服务,统一处理所有客户端请求,实现 RESTful 规范的列表查询、详情查询接口。
// 启动Bun高性能HTTP服务
const server = Bun.serve({
port: 3000, // 服务监听端口:访问地址 http://localhost:3000
// 所有客户端请求都会进入该方法处理
async fetch(req: Request) {
// 配置跨域头部,允许前端页面跨域请求
const headers = {
'Access-Control-Allow-Origin': '*',
}
// 解析客户端请求的完整URL
const url = new URL(req.url);
// 1. RESTful 查询所有任务资源:GET /todos
if (url.pathname === "/todos") {
return Response.json(todos, { headers });
}
// 2. RESTful 查询单个任务详情:GET /todos/:id
if (req.method === "GET" && url.pathname.startsWith("/todos/")) {
// 分割URL路径,获取动态任务ID
const id = url.pathname.split("/")[2];
// 根据ID匹配对应任务
const todo = todos.find(t => t.id === id);
// 匹配成功返回任务详情,失败返回404
if (todo) {
return Response.json(todo, { headers });
} else {
return Response.json({ msg: "Todo not found" }, { status: 404, headers });
}
}
// 默认路由
return Response.json({ msg: "hello bun restful todo server" }, { headers });
}
});
// 打印服务启动日志
console.log(`Server running at http://localhost:${server.port}`);
核心代码逐行解析:
四、前端实战:页面请求渲染 Todo 列表
通过原生 JS fetch 请求后端 RESTful 接口,异步获取任务数据并渲染到页面,完成前后端简易联调。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RESTful TodoList 展示</title>
</head>
<body>
<!– 任务列表渲染容器 –>
<ul id="todos"></ul>
<script>
// 异步请求封装:async/await 优化异步代码可读性
async function main(){
// 请求后端todos资源接口
const res = await fetch("http://localhost:3000/todos");
// 解析json格式响应数据
const data = await res.json();
// 遍历数据,拼接HTML并渲染到页面
todos.innerHTML = data.map(
todo => `<li>${todo.title}</li>`
).join("");
}
// 执行渲染函数
main();
</script>
</body>
</html>
前端代码核心思路:
- 使用 async/await 替代传统 Promise.then 链式调用,代码层级更清晰、可读性更高;
- 直接请求 RESTful 标准资源接口 /todos,无需拼接复杂请求参数;
- 通过数组 map 遍历数据,批量生成 DOM 结构,完成列表渲染。
把后端代码通过bun run (你的文件名).ts运行,然后在html文件用Open with Live Server 打开就好了
五、全文总结
本文从底层理论到代码实战,完整落地了一套极简标准的 RESTful TodoList 项目,打通了「面向接口编程思想」和「RESTful 接口设计规范」的落地逻辑:
首先通过 TypeScript 接口掌握了面向接口编程的核心:接口是数据结构和行为的约束契约,是代码规范化、工程化的基础;其次理解了 RESTful 一切皆资源的核心思想,掌握了「名词资源+HTTP 动词操作」的标准接口设计规则;最后通过 Bun 服务端+前端页面,完成了接口开发、路由匹配、前后端联调的完整实战。
整套方案轻量化、无冗余依赖,既是入门前后端接口开发的最佳案例,也是理解设计模式、接口规范的核心实操项目。
六、核心知识点复盘
七、常见问题 & 避坑指南
7.1 接口定义避坑 ❌ 错误:定义接口后,实际数据缺少字段/字段类型不匹配,TS 不会报错(未开启严格模式) ✅ 解决:开启 TS 严格模式 strict: true,强制校验接口类型一致性,杜绝不规范数据结构。
7.2 RESTful 规范避坑 ❌ 错误:接口路径使用动词(/getTodo、/deleteTodo),不符合 RESTful 语义 ✅ 解决:统一使用资源名词,通过 HTTP 动词区分操作,标准语义化设计。
7.3 动态路由匹配避坑 ❌ 错误:直接通过字符串分割获取 ID,未做参数校验,空 ID、非法 ID 会导致接口报错 ✅ 解决:新增 ID 合法性校验,非空、格式校验后再执行查询逻辑。
7.4 跨域问题避坑 ❌ 错误:未配置 Access-Control-Allow-Origin 请求头,前端本地请求跨域失败 ✅ 解决:服务端统一配置跨域头部,开发环境可临时设为 *,生产环境配置指定域名。
7.5 异步代码避坑 ❌ 错误:使用 fetch 未加 await,直接获取 Promise 对象,导致数据渲染失败 ✅ 解决:fetch 为异步 Promise 方法,必须通过 await或 .then 获取真实数据。


