十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Deno中间件框架开发:从零实现Koa.js风格的洋葱模型 | Deno进阶开发笔记

Deno中间件框架开发:从零实现Koa.js风格的洋葱模型 | Deno进阶开发笔记 Deno中间件框架开发从零实现Koa.js风格的洋葱模型 | Deno进阶开发笔记【免费下载链接】deno_note《Deno进阶开发笔记》 (不定时更新) 项目地址: https://gitcode.com/gh_mirrors/de/deno_noteDeno作为新一代JavaScript/TypeScript运行时凭借其安全性、模块化设计和原生TypeScript支持正逐渐成为后端开发的新选择。本文将带你从零开始在Deno环境中实现一个类似Koa.js的中间件框架深入理解洋葱模型的工作原理并掌握Deno生态下的Web开发核心技术。为什么选择Deno开发中间件框架Deno自2020年正式发布以来已经发展成为一个成熟的运行时环境。与Node.js相比它具有以下优势原生TypeScript支持无需额外配置即可直接运行TypeScript代码安全的默认行为所有文件系统和网络访问都需要显式授权内置工具链包含格式化、测试、文档生成等开发工具现代标准库基于最新的Web标准支持Fetch API、Web Streams等这些特性使得Deno特别适合构建轻量级、高性能的Web框架。在本项目中我们将利用Deno的这些优势实现一个简洁而强大的中间件框架。洋葱模型中间件的核心原理中间件是现代Web框架的核心概念而洋葱模型则是Koa.js等框架最具特色的设计。简单来说洋葱模型允许中间件在请求处理前后都执行代码形成层层包裹的处理流程。洋葱模型的优势在于灵活的请求/响应处理中间件可以在请求到达时执行前置操作在响应发送前执行后置操作统一的错误处理异常可以在任何中间件层被捕获和处理模块化组合不同功能可以封装为独立中间件按需组合使用从零实现Deno中间件框架1. 项目结构与准备首先克隆项目仓库并进入工作目录git clone https://gitcode.com/gh_mirrors/de/deno_note cd de/deno_note我们的中间件框架主要包含以下核心文件demo/web/application.ts应用主类负责管理中间件和启动服务demo/web/compose.ts实现洋葱模型的核心函数demo/web/context.ts封装请求/响应上下文2. 实现洋葱模型的核心compose函数compose函数是洋葱模型的核心它负责按顺序执行中间件并控制流程。以下是实现代码export const compose function (middleware: Function[]) { if (!Array.isArray(middleware)) { throw new TypeError(Middleware stack must be an array!); } return function(ctx: object, next?: Function) { let index -1; return dispatch(0); function dispatch(i: number) { if (i index) { return Promise.reject(new Error(next() called multiple times)); } index i; let fn: any middleware[i]; if (i middleware.length) { fn next; } if (!fn) { return Promise.resolve(); } try { return Promise.resolve(fn(ctx, () { return dispatch(i 1); })); } catch (err) { return Promise.reject(err); } } }; }这个函数接收一个中间件数组返回一个函数该函数接收上下文对象和下一个中间件函数。通过递归调用dispatch函数实现中间件的层层调用和回溯。3. 创建Application类管理中间件Application类是框架的入口点负责注册中间件、创建HTTP服务器和处理请求import { Context, SafeContext } from ./context.ts; import { Server } from ./../server/mod.ts; import { compose } from ./compose.ts; class Application { private _middlewares: Function[]; private _server: Server; constructor() { this._middlewares []; this._server new Server(); } public use(fn: Function): void { this._middlewares.push(fn); } public async listen(opts: Deno.ListenOptions, fn: Function) { const that this; const server this._server; server.createServer(async function(ctx: Context) { const middlewares that._middlewares; try { const sctx new SafeContext(ctx); await compose(middlewares)(sctx); const body sctx.res.getBody(); if (!(body typeof body string body.length 0)) { sctx.res.setBody(404 Not Found!); } await ctx.res.flush(); } catch (err) { that._onError(err, ctx); } }); server.listen(opts, fn); } private async _onError(err: Error, ctx: Context) { console.log(err); if (ctx instanceof Context) { ctx.res.setBody(err.stack || Server Error); ctx.res.setStatus(500); await ctx.res.flush(); } else { Deno.exit(1); } } } export { Application };在listen方法中我们创建了HTTP服务器并在请求到来时使用compose函数执行所有注册的中间件。4. 封装请求/响应上下文Context类封装了HTTP请求和响应对象提供了简洁的API供中间件使用// 简化版Context类示例 export class Context { public req: Request; public res: Response; constructor(req: Request, res: Response) { this.req req; this.res res; } // 提供便捷方法 public set status(code: number) { this.res.status code; } public set body(value: string) { this.res.body value; } }使用示例创建第一个Deno中间件应用现在让我们使用刚刚实现的框架创建一个简单的Web应用import { Application } from ./demo/web/application.ts; const app new Application(); // 日志中间件 app.use(async (ctx, next) { const start Date.now(); await next(); const ms Date.now() - start; console.log(${ctx.req.method} ${ctx.req.url} - ${ms}ms); }); // 响应中间件 app.use(async (ctx) { ctx.res.setBody(Hello Deno Middleware!); ctx.res.setStatus(200); }); // 启动服务器 app.listen({ port: 8000 }, () { console.log(Server running on port 8000); });运行这个应用deno run --allow-net demo/web/example.ts访问http://localhost:8000你将看到Hello Deno Middleware!的响应同时控制台会输出请求日志。进阶技巧中间件的高级用法1. 错误处理中间件利用洋葱模型的特性我们可以创建一个全局错误处理中间件app.use(async (ctx, next) { try { await next(); } catch (err) { ctx.res.setStatus(500); ctx.res.setBody(Server Error: ${err.message}); } });2. 路由中间件我们可以实现一个简单的路由中间件根据URL路径分发请求function router() { const routes: { path: string, handler: Function }[] []; return { get(path: string, handler: Function) { routes.push({ path, handler }); }, middleware: async (ctx, next) { const route routes.find(r r.path ctx.req.url); if (route) { await route.handler(ctx); } else { await next(); } } }; } // 使用路由 const r router(); r.get(/hello, async (ctx) { ctx.res.setBody(Hello Router!); }); app.use(r.middleware);3. 静态文件服务中间件实现一个提供静态文件服务的中间件async function staticMiddleware(ctx: any, next: Function) { const publicDir ./demo/web_static/public; const path ctx.req.url / ? /index.html : ctx.req.url; try { const file await Deno.readFile(${publicDir}${path}); ctx.res.setBody(file); // 设置适当的Content-Type // ... } catch { await next(); } } app.use(staticMiddleware);总结与扩展通过本文的学习我们从零开始实现了一个基于Deno的中间件框架深入理解了洋葱模型的工作原理。这个框架虽然简单但包含了现代Web框架的核心思想。你可以通过以下方式扩展这个框架添加更多便捷的上下文方法实现更强大的路由系统支持参数和通配符添加模板引擎支持实现中间件的级联和嵌套Deno生态系统正在快速发展这个中间件框架只是Deno强大能力的一个缩影。希望本文能帮助你更好地理解Deno和中间件架构为你的下一个项目提供灵感项目完整代码可以在demo/web/目录下找到包含了更多高级特性和示例。【免费下载链接】deno_note《Deno进阶开发笔记》 (不定时更新) 项目地址: https://gitcode.com/gh_mirrors/de/deno_note创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表