在 Web 开发中,路由(Routing) 用来决定“当用户访问某个 URL 时,服务器应该执行哪段逻辑”。在 Node.js 中,无论是使用原生 http 模块,还是使用 Express、Koa 等框架,路由处理都是构建后端应用的核心基础。本篇文章将从原理出发,逐步讲解 Node.js 中的路由处理方式。
http
简单来说,路由就是根据请求的 URL 路径 和 HTTP 方法,匹配到对应的处理函数。
例如:
GET /users
POST /users
GET /users/1
路由的本质是一个映射关系:
请求(method + url) → 处理函数
在 Node.js 中,路由并不是一个内置的高级概念,而是通过代码逻辑实现的。
Node.js 原生的 http 模块并不提供路由系统,需要开发者手动判断。
const http = require("http"); const server = http.createServer((req, res) => { const { method, url } = req; if (method === "GET" && url === "/") { res.writeHead(200, { "Content-Type": "text/plain" }); res.end("Home Page"); } else if (method === "GET" && url === "/about") { res.writeHead(200, { "Content-Type": "text/plain" }); res.end("About Page"); } else { res.writeHead(404, { "Content-Type": "text/plain" }); res.end("Not Found"); } }); server.listen(3000);
这种方式直观,但当路由数量增多时,代码会变得难以维护。
为了提升可维护性,可以将路由逻辑抽象成“路由表”。
const routes = { "GET /": (req, res) => { res.end("Home Page"); }, "GET /about": (req, res) => { res.end("About Page"); } }; const server = http.createServer((req, res) => { const key = `${req.method} ${req.url}`; const handler = routes[key]; if (handler) { res.writeHead(200, { "Content-Type": "text/plain" }); handler(req, res); } else { res.writeHead(404); res.end("Not Found"); } });
这种写法已经接近简单路由系统的雏形。
实际开发中,路由往往包含参数,例如 /users/1。 原生 Node.js 不会自动解析,需要手动处理。
/users/1
if (method === "GET" && url.startsWith("/users/")) { const userId = url.split("/")[2]; res.end(`User ID: ${userId}`); }
这种方式虽然简单,但对复杂路由支持有限。
const userRoute = /^\/users\/(\d+)$/; if (method === "GET" && userRoute.test(url)) { const userId = url.match(userRoute)[1]; res.end(`User ID: ${userId}`); }
正则方式更灵活,但可读性和维护成本较高。
良好的路由设计应当将 路由定义 与 业务逻辑 分离。
function getUsers(req, res) { res.end("User List"); } function createUser(req, res) { res.end("Create User"); } const routes = { "GET /users": getUsers, "POST /users": createUser };
这样做的好处是:
虽然本文重点是 Node.js 原生路由,但理解框架的路由设计非常有帮助。
const express = require("express"); const app = express(); app.get("/users", (req, res) => { res.send("User List"); }); app.post("/users", (req, res) => { res.send("Create User"); }); app.listen(3000);
Express 内部已经帮我们完成了:
理解原生路由后,再使用框架会更加得心应手。
在实际项目中,良好的路由设计非常重要:
使用 RESTful 风格 用 HTTP 方法表达操作语义
保持路由简洁明确 避免过深、过复杂的路径结构
路由分模块管理 按功能拆分路由文件
统一错误处理 避免在每个路由中重复写错误逻辑
通过本篇文章,你应该已经理解:
路由处理是 Node.js 后端开发的基础能力之一。掌握原生实现原理,不仅能写出更清晰的代码,也能更深入理解 Express、Koa 等框架的设计思想。
一、什么是路由处理
简单来说,路由就是根据请求的 URL 路径 和 HTTP 方法,匹配到对应的处理函数。
例如:
GET /users→ 获取用户列表POST /users→ 创建用户GET /users/1→ 获取指定用户路由的本质是一个映射关系:
请求(method + url) → 处理函数在 Node.js 中,路由并不是一个内置的高级概念,而是通过代码逻辑实现的。
二、使用原生 http 模块实现路由
Node.js 原生的
http模块并不提供路由系统,需要开发者手动判断。1. 基于 URL 和方法的路由判断
const http = require("http"); const server = http.createServer((req, res) => { const { method, url } = req; if (method === "GET" && url === "/") { res.writeHead(200, { "Content-Type": "text/plain" }); res.end("Home Page"); } else if (method === "GET" && url === "/about") { res.writeHead(200, { "Content-Type": "text/plain" }); res.end("About Page"); } else { res.writeHead(404, { "Content-Type": "text/plain" }); res.end("Not Found"); } }); server.listen(3000);这种方式直观,但当路由数量增多时,代码会变得难以维护。
2. 抽象路由表
为了提升可维护性,可以将路由逻辑抽象成“路由表”。
const routes = { "GET /": (req, res) => { res.end("Home Page"); }, "GET /about": (req, res) => { res.end("About Page"); } }; const server = http.createServer((req, res) => { const key = `${req.method} ${req.url}`; const handler = routes[key]; if (handler) { res.writeHead(200, { "Content-Type": "text/plain" }); handler(req, res); } else { res.writeHead(404); res.end("Not Found"); } });这种写法已经接近简单路由系统的雏形。
三、处理带参数的路由
实际开发中,路由往往包含参数,例如
/users/1。 原生 Node.js 不会自动解析,需要手动处理。1. 基于字符串匹配
if (method === "GET" && url.startsWith("/users/")) { const userId = url.split("/")[2]; res.end(`User ID: ${userId}`); }这种方式虽然简单,但对复杂路由支持有限。
2. 使用正则匹配路由
const userRoute = /^\/users\/(\d+)$/; if (method === "GET" && userRoute.test(url)) { const userId = url.match(userRoute)[1]; res.end(`User ID: ${userId}`); }正则方式更灵活,但可读性和维护成本较高。
四、路由与业务逻辑解耦
良好的路由设计应当将 路由定义 与 业务逻辑 分离。
function getUsers(req, res) { res.end("User List"); } function createUser(req, res) { res.end("Create User"); } const routes = { "GET /users": getUsers, "POST /users": createUser };这样做的好处是:
五、Express 中的路由机制(对比理解)
虽然本文重点是 Node.js 原生路由,但理解框架的路由设计非常有帮助。
const express = require("express"); const app = express(); app.get("/users", (req, res) => { res.send("User List"); }); app.post("/users", (req, res) => { res.send("Create User"); }); app.listen(3000);Express 内部已经帮我们完成了:
理解原生路由后,再使用框架会更加得心应手。
六、路由设计的最佳实践
在实际项目中,良好的路由设计非常重要:
使用 RESTful 风格 用 HTTP 方法表达操作语义
保持路由简洁明确 避免过深、过复杂的路径结构
路由分模块管理 按功能拆分路由文件
统一错误处理 避免在每个路由中重复写错误逻辑
七、总结
通过本篇文章,你应该已经理解:
路由处理是 Node.js 后端开发的基础能力之一。掌握原生实现原理,不仅能写出更清晰的代码,也能更深入理解 Express、Koa 等框架的设计思想。