首页/新闻资讯/正文详情

Egg.js HTTP Controller 装饰器实战指南:声明式路由、参数注入与响应定制

发布时间:2026/9/21 7:27:55 来源:云帆数科 栏目:资讯中心
Egg.js HTTP Controller 装饰器实战指南:声明式路由、参数注入与响应定制
后端Web框架【免费下载链接】egg Born to build better enterprise frameworks and apps with Node.js Koa. https://307.run/eggcode项目地址https://gitcode.com/gh_mirrors/eg/egg点击查看免费下载导读HTTP Controller 是 Egg.js基于 TypeScript 的声明式编程模型 tegg中用于声明 HTTP 接口的核心机制。通过HTTPController与HTTPMethod装饰器你可以将类 方法直接映射为路径 HTTP 方法无需手写路由表再配合HTTPParam、HTTPQuery、HTTPBody等参数装饰器框架会自动把 HTTP 请求中的各项数据解析并注入到方法参数中。读完本文你将掌握如何声明接口、理解路径优先级规则、熟练使用全部请求参数装饰器并针对默认 JSON 响应之外的场景自定义响应与流式输出。本指南对应的完整文档位于 site/docs/basics/httpcontroller.md示例代码可在 examples/helloworld-tegg/app/port/controller 中查看。使用场景当你需要在应用中提供 HTTP 服务时使用HTTPController装饰器声明 HTTP 接口。它特别适合强依赖 HTTP 协议的场景常见的有SSR 场景在服务端渲染 HTML 并返回给前端SSE 场景通过 Server-Sent Events 与前端实时通信例如实现 AI 对话流式输出依赖 HTTP 协议数据如 Cookie做业务逻辑的场景。从底层实现看控制器会被声明为ControllerType.HTTP见 HTTPController.ts 中ControllerInfoUtil.setControllerType(constructor, ControllerType.HTTP)一行并由 EggHTTPControllerRegistrar.ts 在加载单元创建完成后统一注册进 Egg 的 Router。基本用法声明一个 HTTP 接口使用HTTPController装饰器声明一个类为 HTTP 控制器使用HTTPMethod装饰器声明类中方法对应的具体 HTTP 接口信息。import { HTTPController, HTTPMethod, HTTPMethodEnum, HTTPParam } from egg; HTTPController() export default class SimpleController { // 声明一个 GET /api/hello/:name 接口 HTTPMethod({ method: HTTPMethodEnum.GET, path: /api/hello/:name }) async hello(HTTPParam() name: string) { return { message: hello name, }; } }HTTPController装饰器支持传入path参数来指定控制器的基准 HTTP 路径它会与HTTPMethod中的path参数拼接构成最终的 HTTP 路径。import { HTTPController, HTTPMethod, HTTPMethodEnum } from egg; // 设置 path 参数指定本类所有接口的路径前缀 HTTPController({ path: /api }) export default class PathController { // GET /api/hello HTTPMethod({ method: HTTPMethodEnum.GET, path: hello }) async hello() { // ... } // POST /api/echo HTTPMethod({ method: HTTPMethodEnum.POST, path: echo }) async echo() { // ... } }从源码可以看到HTTPController装饰器除了记录控制器类型与路径外还会通过SingletonProto把该类声明为单例对象见 HTTPController.ts而HTTPMethod装饰器则会把path、method、timeout、priority等信息逐一记录到方法元数据中见 HTTPMethod.ts。接口方法在运行期会被包装为 Egg 中间件框架从容器中取出控制器实例、按元数据解析参数、调用方法并将返回值写入ctx.body核心逻辑见 EggHTTPMethodRegister.ts。路径优先级HTTPMethod装饰器中设置的path使用 path-to-regexp 解析支持简单参数、通配符等特性。当多个HTTPMethod装饰器同时满足路径匹配时需要优先级来决定最终命中的接口优先级越高的接口越先被匹配。Egg 为每个接口自动计算优先级。默认优先级规则可以满足绝大多数场景因此大多数情况下无需手动指定。默认规则如下priority pathHasRegExp ? regexpIndexInPath.reduce((p,c) p c * 1000, 0) : 100000结合具体示例以下接口的默认优先级从低到高排列为PathRegExp indexpriority/*[0]0/hello/:name[1]1000/hello/world/message/:message[3]3000/hello/:name/message/:message[1, 3]4000/hello/world[]100000可以看到路径中包含的正则表达式参数、通配符越多优先级越低完全静态的路径优先级最高100000。对于默认优先级无法满足的业务场景可以通过HTTPMethod装饰器的priority参数手动指定优先级。import { HTTPController, HTTPMethod, HTTPMethodEnum } from egg; HTTPController() export default class PriorityController { HTTPMethod({ method: HTTPMethodEnum.GET, path: /(api|openapi)/echo, priority: 100000, // 为该接口指定更高优先级 }) async high() { // ... } HTTPMethod({ method: HTTPMethodEnum.POST, path: /(api|openapi)/(.), }) async low() { // ... } }请求参数装饰器HTTPHeadersHTTPHeaders装饰器用于获取完整的 HTTP 请求头。:::warning ⚠️ 注意headers 中的 key 会被转换为小写取值时请使用小写字符。 :::import { HTTPController, HTTPMethod, HTTPMethodEnum, HTTPHeaders, IncomingHttpHeaders } from egg; HTTPController() export default class ArgsController { // curl http://localhost:7001/api/hello -H X-Custom: custom HTTPMethod({ method: HTTPMethodEnum.GET, path: /api/hello }) async getHeaders(HTTPHeaders() headers: IncomingHttpHeaders) { const custom headers[x-custom]; // ... } }从源码看该装饰器将参数类型标记为HTTPParamType.HEADERS见 HTTPParam.ts运行期由 EggHTTPMethodRegister.ts 直接将ctx.request.headers注入到参数中。HTTPQuery / HTTPQueriesHTTPQuery和HTTPQueries装饰器用于获取 HTTP 请求中的 querystring 参数。HTTPQuery只取第一个参数值类型必须为stringHTTPQueries以数组形式注入一个或多个值类型为string[]。import { HTTPController, HTTPMethod, HTTPMethodEnum, HTTPQuery, HTTPQueries } from egg; HTTPController() export default class ArgsController { HTTPMethod({ method: HTTPMethodEnum.GET, path: /api/query }) async getQueries( // /api/query?userasduserfgh // user asd // users [asd, fgh] HTTPQuery() user?: string, // 不设置 name 时默认使用变量名 HTTPQueries({ name: user }) users?: string[], // 也可以手动指定 name ) { // ... } }这里有一个值得注意的细节HTTPQuery/HTTPQueries/HTTPParam这三个装饰器在未指定name时会通过ObjectUtils.getFunctionArgNameList解析函数参数名自动作为参数名见 HTTPParam.ts 中const name param?.name || argNames[parameterIndex]一行。由于 TypeScript 编译后参数名可能丢失如需保证稳定建议显式传入name。运行期HTTPQuery读取的是ctx.query[name]HTTPQueries读取的是ctx.queries[name]见 EggHTTPMethodRegister.ts。HTTPParamHTTPParam装饰器用于获取 HTTP 请求path中匹配到的路径参数类型只能是string。参数名默认与变量名一致有别名需求时也可手动指定。import { HTTPController, HTTPMethod, HTTPMethodEnum, HTTPParam } from egg; HTTPController() export default class ArgsController { // curl http://127.0.0.1:7001/api/2088000 HTTPMethod({ method: HTTPMethodEnum.GET, path: /api/:id }) async getParamId(HTTPParam() id: string) { // id 的值为 2088000 // ... } // 匹配 path 中第一个被正则捕获的字符 HTTPMethod({ method: HTTPMethodEnum.GET, path: /foo/(.*) }) async getParamBar(HTTPParam({ name: 0 }) bar: string) { // ... } }HTTPBodyHTTPBody装饰器用于获取请求体内容。注入时框架会根据请求头中的content-type解析请求体支持json、text、form-urlencoded其他content-type类型会注入空值。如需获取原始请求体可通过Request装饰器自行处理。import { HTTPController, HTTPMethod, HTTPMethodEnum, HTTPBody } from egg; export interface BodyData { foo: string; bar?: number; } HTTPController() export default class ArgsController { // content-type: application/json HTTPMethod({ method: HTTPMethodEnum.POST, path: /api/json-body }) async getJsonBody(HTTPBody() body: BodyData) { // ... } // content-type: text/plain HTTPMethod({ method: HTTPMethodEnum.POST, path: /api/text-body }) async getTextBody(HTTPBody() body: string) { // ... } // content-type: application/x-www-form-urlencoded HTTPMethod({ method: HTTPMethodEnum.POST, path: /api/formdata-body }) async getFormBody( HTTPBody() body: FormData, // 函数应用中为 FormData 类型 // HTTPBody() body: BodyData, // 标准应用中为普通对象 ) { // ... } }运行期HTTPBody注入的是ctx.request.body见 EggHTTPMethodRegister.ts即 Egg 解析后的请求体对象与标准应用中的用法一致。CookiesCookies装饰器用于获取完整的 HTTP Cookies。import { Cookies, HTTPController, HTTPMethod, HTTPMethodEnum, HTTPCookies } from egg; HTTPController() export default class ArgsController { HTTPMethod({ method: HTTPMethodEnum.POST, path: /api/cookies }) async getCookies(HTTPCookies() cookies: Cookies) { return { success: true, cookies: cookies.get(test, { signed: false }), }; } }HTTPRequestHTTPRequest装饰器用于获取完整的 HTTP 请求对象可以获取 url、headers、body 等请求信息具体 API 请参考类型定义。:::warning ⚠️ 注意通过HTTPBody注入请求体后请求体即被消费。如果同时注入HTTPRequest并再次消费请求体会报错注入HTTPRequest但仅获取 url、headers 等、不消费请求体则不受影响。 :::import { HTTPBody, HTTPController, HTTPMethod, HTTPMethodEnum, HTTPRequest } from egg; HTTPController() export default class ArgsController { HTTPMethod({ method: HTTPMethodEnum.POST, path: /api/request }) async getRequest(HTTPRequest() request: Request) { const headerData request.headers.get(x-header-key); const url request.url; // 获取请求体 arrayBuffer const arrayBufferData await request.arrayBuffer(); // ... } HTTPMethod({ method: HTTPMethodEnum.POST, path: /api/request2 }) async getRequest2(HTTPBody() body: object, HTTPRequest() request: Request) { // 同时注入 HTTPBody 和 Request通过 request 读取 header、url 等正常工作 const headerData request.headers.get(x-header-key); const url request.url; // ❌ 错误示例 // 当请求体已通过 HTTPBody 注入后 // 再通过 request 消费请求体会抛出异常 // const arrayBufferData await request.arrayBuffer(); // ... } }这里的Request是标准 Web API 的 Request 对象要求 Node.js 版本 16见 HTTPParam.ts 中assert(nodeMajor 16, ...)的断言。框架在运行期通过 Req.ts 中的initRequest基于ctx.request.href、method、headers 与rawBody构造该对象因此请求体消费是独占性的。该场景的完整示例可参考 examples/helloworld-tegg/app/port/controller/ArgsController.ts其中getRequest与getRequest2展示了这两种注入方式的实际效果。HTTPContext在标准应用中可以使用HTTPContext装饰器获取 Egg 的 Context 对象。:::warning ⚠️ 注意函数应用中不支持HTTPContext装饰器。 :::import { HTTPContext, Context, HTTPController, HTTPMethod, HTTPMethodEnum } from egg; HTTPController() export default class ArgsController { HTTPMethod({ method: HTTPMethodEnum.GET, path: /api/context }) async getContext(HTTPContext() context: Context) { // ... } }HTTPContext本质是InjectContext的别名见 HTTPParam.ts 末尾的导出运行期框架会把当前请求的ctx直接注入该参数见 EggHTTPMethodRegister.ts 中args[contextIndex!] ctx一行。HTTP 响应默认响应默认情况下当HTTPMethod函数返回对象时框架会使用JSON.stringify处理并设置Content-Type: application/json返回给客户端。import { HTTPController, HTTPMethod, HTTPMethodEnum } from egg; HTTPController() export default class ResponseController { HTTPMethod({ method: HTTPMethodEnum.GET, path: /api/json }) async defaultResponse() { return { result: hello world, }; } }自定义响应函数应用在函数应用中当需要返回非 JSON 数据或设置 HTTP 响应码、响应头时可以通过全局注入的Response对象设置并返回。import { HTTPController, HTTPMethod, HTTPMethodEnum } from egg; HTTPController() export default class ResponseController { HTTPMethod({ method: HTTPMethodEnum.GET, path: /api/custom-response }) async customResponse() { // Response 是全局对象无需 import return new Response(h1Hello World/h1, { status: 200, headers: { transfer-encoding: chunked, content-type: text/html; charsetutf-8, x-header-key: from-function, }, }); } }标准应用在标准应用中可以使用 Context 提供的 API 自定义 HTTP 响应码和响应头。import { Context, HTTPContext, HTTPController, HTTPMethod, HTTPMethodEnum } from egg; HTTPController() export default class ResponseController { HTTPMethod({ method: HTTPMethodEnum.GET, path: /api/custom-response }) async customResponse(HTTPContext() ctx: Context) { // 自定义响应码 ctx.status 200; // 添加自定义响应头 ctx.set(x-custom, custom); // 设置 Content-Type 的语法糖等价于 ctx.set(content-type, application/json) // 支持 json、html 等常见类型见 https://github.com/jshttp/mime-types ctx.type html; return h1Hello World/h1; } }关于标准应用中 Context 的更多能力如ctx.app、ctx.logger、ctx.helper等可阅读 site/docs/basics/objects.md。流式响应只需将流式数据包装为Readable对象并返回即可。import { Readable } from node:stream; import { setTimeout } from node:timers/promises; import { Context, HTTPContext, HTTPController, HTTPMethod, HTTPMethodEnum } from egg; // 构造流式数据 async function* generate(count 5, duration 500) { yield htmlheadtitlehello stream/title/headbody; for (let i 0; i count; i) { yield h2Stream content ${i 1}, ${Date()}/h2; await setTimeout(duration); } yield /body/html; } HTTPController() export default class ResponseController { HTTPMethod({ method: HTTPMethodEnum.GET, path: /api/stream }) async streamResponse(HTTPContext() ctx: Context) { ctx.type html; return Readable.from(generate()); } }流式响应非常适合 SSE 等实时通信场景方法返回Readable对象后框架会将其写入ctx.body由 Koa 逐块输出到客户端从而实现边生成边推送的效果。小结本文围绕 site/docs/basics/httpcontroller.md 的核心内容完整介绍了 Egg.js HTTP Controller 的声明方式、路径拼接与优先级规则、全部请求参数装饰器HTTPHeaders、HTTPQuery/HTTPQueries、HTTPParam、HTTPBody、HTTPCookies、HTTPRequest、HTTPContext以及默认/自定义/流式三类响应写法。这些装饰器的元数据定义集中在 tegg/core/controller-decorator/src/decorator/http/HTTPParam.ts 与 HTTPMethod.ts运行期的参数注入与路由注册实现在 tegg/plugin/controller/src/lib/impl/http 目录下动手实践时可以直接参考 examples/helloworld-tegg/app/port/controller 中的完整示例并结合 examples/helloworld-tegg/test 中的测试用例验证行为。赞分享后端Web框架【免费下载链接】egg Born to build better enterprise frameworks and apps with Node.js Koa. https://307.run/eggcode项目地址https://gitcode.com/gh_mirrors/eg/egg点击查看免费下载相关推荐Remix 路由与控制器实战指南从 URL 声明到类型安全响应Remix 路由与控制器实战指南从 URL 声明到类型安全响应 导读 本文是 Remix 全栈框架路由模块的核心参考围绕 .agents/skills/re后端前端Web框架strategic-compact技能详解Everything Claude Code如何建议最佳压缩时机strategic compact技能详解Everything Claude Code如何建议最佳压缩时机 在 Everything Claude CodeAI 插件AI 技能AI 评测Wasp 自定义 HTTP API 端点api 声明完整实战指南路由、认证、中间件与实体注入Wasp 自定义 HTTP API 端点api 声明完整实战指南路由、认证、中间件与实体注入 本篇指南围绕 Wasp当前仓库为 GitHub_TrendWeb框架后端前端CLI开发工具上一篇终极Werkzeug调试器实战指南如何在浏览器中实时调试Python代码错误下一篇彻底搞懂Keras Stateful RNN避免90%的时间序列预测错误创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Flet WebView 扩展实战指南:用 flet-webview 在 Python 应用中嵌入网页内容
Flet WebView 扩展实战指南:用 flet-webview 在 Python 应用中嵌入网页内容

前端跨平台桌面应用移动开发 【免费下载链接】flet Build realtime web, mobile and desktop apps in Python only. No frontend experience required. 项目地址: https://gitcode.com/gh_mirrors/fl/flet 点击查看 免费下载 flet-webview 是 Flet 官方推出的扩展包… · 2026/9/21 7:27:55

MCP Python SDK 服务端 lifespan 全解:从连接池管理到生命周期验证实战
MCP Python SDK 服务端 lifespan 全解:从连接池管理到生命周期验证实战

MCP Python SDK 服务端 lifespan 全解:从连接池管理到生命周期验证实战 【免费下载链接】python-sdk The official Python SDK for Model Context Protocol servers and clients 项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk 导读 本篇文… · 2026/9/21 7:26:55

Vue Router 2 构造选项全解析:routes、mode、base 与 scrollBehavior 配置指南
Vue Router 2 构造选项全解析:routes、mode、base 与 scrollBehavior 配置指南

前端路由 【免费下载链接】vue-router 🚦 The official router for Vue 2 项目地址: https://gitcode.com/gh_mirrors/vu/vue-router 点击查看 免费下载 本篇技术指南以 Vue Router 2(本仓库 vu/vue-router)官方文档《Options de… · 2026/9/21 7:26:55

企业网站做电脑营销多少钱?揭秘防黑挂马的底层逻辑
企业网站做电脑营销多少钱?揭秘防黑挂马的底层逻辑

企业网站做电脑营销多少钱?揭秘防黑挂马的底层逻辑 网站突然被黑,首页挂满赌博广告,后台密码怎么改都没用,这种绝望感做过站的都懂。很多老板第一反应是问:“清理一次病毒多少钱?”或者“换个服务器多少钱?”但真相往往扎心:单纯清理病毒的费用可能只要几百块,但重建信任、修复SEO权重、补全安全漏洞的成本,往… · 2026/9/21 8:03:27

3步搞定做品管圈网站从零搭建到上线避坑指南
3步搞定做品管圈网站从零搭建到上线避坑指南

3步搞定做品管圈网站从零搭建到上线避坑指南 不会写代码,但想给团队搭个品管圈展示平台?别慌。 很多河南的创业老板都卡在这一步:手里有现成的QCC成果,想做个官网放上去,结果一搜全是“前端开发教程”,看得头大。 做品管圈网站 这事儿,真没你想的那么玄乎。只要路子对,零基础也能 从零搭建… · 2026/9/21 7:45:56

Voyager 資料夾管理指南:為 Gemini 與 AI Studio 的 AI 對話打造真正的「檔案系統」
Voyager 資料夾管理指南:為 Gemini 與 AI Studio 的 AI 對話打造真正的「檔案系統」

AI 应用前端 【免费下载链接】voyager Enhancement suite for Gemini, AI Studio, Claude & ChatGPT — plus a prompt manager for any websites, DeepSeek Harness included. / 面向 Gemini、AI Studio、Claude 与 ChatGPT 的增强套件;其中的提示词管理器可用… · 2026/9/21 7:41:58

gatsby-source-graphql 插件全解析:将任意第三方 GraphQL API 缝合进 Gatsby 数据层
gatsby-source-graphql 插件全解析:将任意第三方 GraphQL API 缝合进 Gatsby 数据层

前端静态站点Web框架 【免费下载链接】gatsby React-based framework with performance, scalability, and security built in. 项目地址: https://gitcode.com/gh_mirrors/ga/gatsby 点击查看 免费下载 本篇技术指南以 gatsby-source-graphql 插件的 CHANGELOG 版… · 2026/9/21 7:41:58

Lightweight Charts v3 到 v4 迁移指南:破坏性变更逐项分析与实战改造方案
Lightweight Charts v3 到 v4 迁移指南:破坏性变更逐项分析与实战改造方案

Lightweight Charts v3 到 v4 迁移指南:破坏性变更逐项分析与实战改造方案 【免费下载链接】lightweight-charts Performant financial charts built with HTML5 canvas 项目地址: https://gitcode.com/gh_mirrors/li/lightweight-charts 本指南以 Lightweig… · 2026/9/21 7:41:58

FoundationDB 存储基准测试上 RAM Disk:mako_storage_bench.sh 在 okteto 开发 Pod 上的 tmpfs 实践指南
FoundationDB 存储基准测试上 RAM Disk:mako_storage_bench.sh 在 okteto 开发 Pod 上的 tmpfs 实践指南

分布式数据库KV存储数据库后端 【免费下载链接】foundationdb FoundationDB - the open source, distributed, transactional key-value store 项目地址: https://gitcode.com/gh_mirrors/fo/foundationdb 点击查看 免费下载 mako_storage_bench.sh 是 FoundationD… · 2026/9/21 7:41:58

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化
Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡… · 2026/9/21 0:02:39

Word表格编号全攻略:从列表编号到题注交叉引用
Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技… · 2026/9/21 0:02:39

从第一个站到第二个站:独立开发者的静态网站选型与落地实践
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&… · 2026/9/20 0:00:41

Claude Code 按智谱AI指南装完,ANTHROPIC_BASE_URL 改走 TaoToken 兼容通道行不行
Claude Code 按智谱AI指南装完,ANTHROPIC_BASE_URL 改走 TaoToken 兼容通道行不行

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/21 0:00:18

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程
agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and … · 2026/9/21 0:00:18

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,… · 2026/9/21 0:00:18

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码