Hyperf注解路由需遵循可读性、可维护性与运行时安全规范:控制器用@Controller显式声明小写无尾斜杠前缀,方法级路由须带HTTP方法注解及动态段正则约束,参数优先类型提示并辅以@Param/@Query/@Body注解,中间件应声明式挂载于路由注解中。

Hyperf 注解路由不是“写对就行”,而是有一套兼顾可读性、可维护性与运行时安全的实践规范。核心是让路由声明清晰表达意图,同时借助框架能力把校验和治理提前到入口层。
控制器类层面:明确职责与前缀
使用 @Controller 声明控制器,并显式指定基础路径前缀,避免隐式拼接带来的歧义。前缀应为小写、无斜杠结尾(如 /api/v1),不带版本号的控制器建议用 @AutoController 自动推导路径。
- 推荐写法:
#[Controller("/api/v1/users")] - 避免写法:
#[Controller("users/")](开头无/易导致路径错乱)或#[Controller("/api/v1/users/")](结尾多余/) - 若控制器仅含单个方法且无需前缀,可直接用
#[AutoController],Hyperf 会按类名和方法名自动生成路径(如IndexController::index→/index/index)
方法级路由:HTTP 方法 + 路径 + 格式约束
每个方法必须使用明确的 HTTP 方法注解(#[GetMapping]、#[PostMapping] 等),路径中动态段必须带正则约束,杜绝裸占位符。
- ✅ 正确:
#[GetMapping("/users/{id:\d+}")]—— 强制id为纯数字,404 拦截非法输入 - ❌ 危险:
#[GetMapping("/users/{id}")]——id可为任意字符串,需在方法内手动校验,增加业务负担且易遗漏 - 路径静态部分保持语义清晰,资源名用复数名词,如
/orders、/products,不用动词式命名(如/getOrders)
参数注入:类型提示优先,注解补充语义
请求参数优先通过类型提示自动注入(如 RequestInterface $request),路径、查询、请求体等结构化参数再用对应注解标注,不混用或冗余声明。
- 路径参数用
#[Param],并确保其名称与路径占位符一致:#[Param("id")] int $id - 查询参数用
#[Query],支持默认值和类型转换:#[Query(default: 10)] int $limit - 请求体数据用
#[Body],配合 DTO 类型提示实现自动验证与反序列化 - 避免在方法签名中同时写
int $id和#[Param] $id—— 注解已承担绑定职责,类型提示负责类型保障
中间件与分组:声明式挂载,避免硬编码
中间件应直接在路由注解中声明,而非在控制器构造函数或方法内调用。跨多个路由的公共中间件,可通过配置文件统一管理,但单一路由强依赖的中间件(如登录态校验、限流)必须在注解中显式写出。
- 推荐:
#[PostMapping("/login", middleware: [ThrottleMiddleware::class, JwtAuthMiddleware::class])] - 不推荐:在
login()方法开头手动调用$this->middleware(...)或在构造函数中注册 - 注意中间件执行顺序:数组中靠前的先执行,如限流应在鉴权之前,防止恶意请求绕过频率控制



















