控制器负责处理传入的请求,并返回对客户端的响应。
控制器使用装饰器 @Controller()
import { Controller } from '@tiger/common'
@Controller()
export default class User {
// ...
}
控制器使用 @Controller([prefix])
装饰器来表示该控制器使用了路由功能
import { Controller } from '@tiger/common'
// 当前控制器的端点访问以 '/users' 开头 (可省略开头 '/')
@Controller('/users')
export default class {
// ...
}
框架提供了 Get
, Post
, Put
,Patch
,Delete
,Head
,Option
, All
装饰器,用于创建访问路由:
import { Controller, Get, Put } from '@tiger/common'
// 当前控制器的端点访问以 '/users' 开头 (可省略开头 '/')
@controller('users')
export class User {
// get /users
@Get()
index() {
// ...
}
// put /users/:id
@Put(':id')
update(id) {
// ...
}
}
上面代码会自动创建get
方法访问的/users
的端点与put
方法访问的/users/:id
的端点
@http.all
装饰器会使用所有http
模块支持的方法,详细信息见http
模块的http.METHODS
属性
在某些情况下,我们可能需要支持一个控制器多个路由前缀的情况
import { Controller, Get, Put } from '@tiger/common'
// 通过添加多个 `@route` 参数来注册多个前缀的路由
@Controller('/users', '/users-old')
export default class User {
// get /users
@Get()
index() {
// ...
}
// put /users/:id
@Put(':id')
update(id) {
// ...
}
}
在某些情况下,我们也可能需要同一个控制器方法支持多个路由访问
import { Controller, Get, All, Post } from '@tiger/common'
@Controller('/users')
export class User {
@Get()
@Post('/post')
index() {
// ...
}
@All('/all', ['get', 'post']) // 第二个参数可选,默认加载 http 所有 method(不推荐)
index2() {
// ...
}
}
路由的参数框架会自动注入到控制器方法中:
import { Controller, Get } from '@tiger/common'
@Controller()
export class User {
@Get('/:name/:age')
index(name, age) {
// ...
}
}
路由参数根据定义顺序注入
使用 @Rest
装饰器代替 @Controller
装饰器,并且默认 Rest
方法无需添加装饰器:
import { Rest } from '@tiger/common'
@Rest('posts')
export class Post {
/**
* Get /posts
* 索引/列表
*/
index() {
//
}
/**
* Get /posts/create
* 创建(显示表单)
*/
create() {
//
}
/**
* Get /posts/:id
* 获取对应id的内容
* @param {number} id
*/
show(id) {
//
}
/**
* Get /posts/:id/edit
* 编辑(显示表单)
* @param {number} id
*/
edit(id) {
//
}
/**
* Post /posts
* 保存你创建的数据
*/
store() {
//
}
/**
* Put /posts/:id
* 保存你编辑的数据
* @param {number} id
*/
update(id) {
//
}
/**
* Delete /posts/:id
* 删除对应id的内容
* @param {number} id
*/
destroy(id) {
//
}
}
内置 Rest
风格方法:
请求类型 | 资源地址 | 控制器方法 | 说明 |
---|---|---|---|
get | /posts | index() | 索引/列表 |
get | /posts/create | create() | 创建(显示表单) |
post | /posts | store() | 保存你创建的数据 |
get | /posts/:id | show(id) | 获取对应id的内容 |
get | /posts/:id/edit | edit(id) | 编辑(显示表单) |
put | /posts/:id | update(id) | 保存你编辑的数据 |
delete | /posts/:id | destroy(id) | 删除对应id的内容 |
Tiger
采用了类似前缀树的数据结构来存储路由,例如我们有一个 path
: /business/users/posts/:post_id
, 那么它的结构就是一个链表:
+----------+ +-----------+ +-------+ +----------+
| business | --> | users | --> | posts | --> | :post_id |
+----------+ +-----------+ +-------+ +----------+
接下来如果继续注册 /business/orders/:order_id
, 那么这个结构就会变成
+----------+ +-----------+ +-------+ +----------+
| business | --> | users | --> | posts | --> | :post_id |
+----------+ +-----------+ +-------+ +----------+
|
|
v
+----------+ +-----------+
| orders | --> | :order_id |
+----------+ +-----------+
为了增加匹配的性能,我们将路由分成了三种类型 静态类型
, 正则类型
, 全匹配类型
静态类型
静态类型就是指字符串完全匹配的类型,避免所有节点都需要正则匹配,降低性能
正则类型
只有注册了路由参数/正则的节点才会进行正则匹配
全匹配类型
全匹配类型是指以 /*
结尾的路由,它可以匹配后续任何参数
框架会自动为注册的路由指定优先级,优先级策略如下: