url
url
url
参数用于匹配客户端请求,支持多种模式:固定路径
、资源路径
、位置参数
、通配符
、类型与验证
固定路径
使用完整url路径,当客户端请求和url参数完全一致时,路由将匹配成功。
示例
import {HttpServer} from "http";
let server = new HttpServer();
server.any("/test", (ctx) => {
ctx.body = "ok";
});
server.start();
资源路径
如果路径以/结尾,则表示匹配该路径下的所有资源。
示例
当url为/test/
时,会匹配路径是/test/
的所有请求,例如:/test/a
、/test/a/b
import {HttpServer} from "http";
let server = new HttpServer();
server.any("/test/", (ctx) => {
ctx.body = "ok";
});
server.start();
位置参数
在url中通过{}
可以将路径映射为变量,参数位置固定,参数名称可以随意命名,并且它们在路径中按位置匹配,并且通过ctx.request.param
可以获取到该url中绑定的变量。
示例
import {HttpServer} from "http";
let server = new HttpServer();
server.any("/test/{name}/{id}", (ctx) => {
let x = ctx.request.param;
console.log(x);
ctx.body = "ok";
});
server.start();
当请求地址是/test/hello/vino
时,通过ctx.request.param
可以获取路径变量。 结果为:
{
name: "hello",
id: "vino"
}
同时/test/{name}/{id}
会匹配所有/test/x/x
的请求,x
为任何合法的名称
通配符
通配符路径允许匹配路径的一部分,然后捕获剩余的部分作为参数。使用 *
作为通配符
示例
import {HttpServer} from "http";
let server = new HttpServer();
server.any("/test/*id", (ctx) => {
let x = ctx.request.param;
console.log(x);
ctx.body = "ok";
});
server.start();
这会匹配任何以路径是/test/
的请求,并将之后的路径保存到ctx.request.param
中。
当请求是/test/path/to/file.txt
时,ctx.request.param
的结果如下:
{
id: "path/to/file.txt"
}
类型与验证
在定义路径参数时,除了指定参数名称,还可以通过类型和验证约束来限定参数的值。这种方式提供了更强的类型安全和数据验证。
语法
{paramName:type func}
参数
- paramName : 变量名。
路由匹配成功后,可以通过
ctx.request.param.[paramName]
来获取参数内容。 - type : 参数类型。
用于指定URL路径参数的预期类型,并对传入的参数进行验证和转换。定义了参数的数据类型(如整数、字符串等),并确保传入的参数符合预期类型的要求。
- func : (可选) 扩展函数。
用来进一步约束参数的值。这些扩展函数可以用于验证参数的范围、长度、模式等。
支持的类型
参数类型 | vino类型 | 验证 |
---|---|---|
:string | string | 任何字符(单个路径段) |
:uuid | string | uuidv4 或 v1(单个路径段) |
:int | number | 整数 |
:bool | boolean | 1 、 t 、 T 、 TRUE 、 true 、 True 、 0 、 f 、 F 、 FALSE 、 false 、 False |
:alphabetical | string | 小写或大写字母 |
:file | string | 小写或大写字母、数字、下划线 (_)、横线 (-)、点 (.) |
:path | string | 任何东西,可以由斜杠(路径段)分隔,但应是路由路径的最后部分 |
:mail | string | 不进行域名验证的电子邮件 |
:email | string | 进行域名验证的电子邮件 |
:date | string | yyyy/mm/dd 格式,例如 /blog/{param:date} 匹配 /blog/2022/04/21 |
支持的扩展函数
函数 | 参数类型 | 说明 |
---|---|---|
regexp(expr string) | :string | 正则表达式匹配 |
prefix(prefix string) | :string | 前缀匹配 |
suffix(suffix string) | :string | 后缀匹配 |
contains(s string) | :string | 包含某一个字符串 |
min(minValue int) | :int | 最小值 |
max(maxValue int) | :int | 最大值 |
range(minValue int, maxValue int) | :int | 数值区间 |
示例
- string: 任何数据(单个路径段)
例如:/test/{username:string}
- uuid: uuidv4 或 v1(单个路径段)
例如:/test/{name:uuid}
- int: 匹配整数值
例如:/test/{id:int}
- bool: 匹配布尔类型
例如:/test/{id:bool}
- alphabetical: 匹配仅包含字母的字符串
例如:/test/{name:alphabetical}
- file: 匹配文件名(包括扩展名)
例如:/test/{filename:file}
- path: 匹配路径,包括斜杠
例如:/test/{filepath:path}
- mail: 不进行域名验证的电子邮件
例如:/test/{m:mail}
- email: 不进行域名验证的电子邮件
例如:/test/{m:email}
- date: 匹配日期格式:yyyy/mm/dd
例如:/test/{m:date}
- regexp: 字符串参数必须匹配给定的正则表达式
例如: {username:string regexp(^[a-zA-Z0-9_]+$)}
,表示 username
必须由字母、数字和下划线组成。
- prefix: 指定前缀
例如: {username:string prefix(abc}
,表示 username
的前缀必须是abc。
- suffix: 指定后缀
例如: {username:string suffix(abc}
,表示 username
的后缀必须是abc。
- contains: 指定包含
例如: {username:string contains(abc}
,表示 username
中必须包含abc。
- min: 参数的最小值
例如: {id:int min(1)}
,表示 id 的最小值是 1。
- max: 参数的最大值
例如: {age:int max(100)}
,表示 age 的最大值是 100。
- range: 参数的值必须在指定范围内
例如: {score:int range(0,100)}
,表示 score
的值在 0 到 100 之间。
路由匹配规则
vino
提供了多种url方式,如果一个请求的 URL 同时匹配到了多个路由,框架会根据一定的规则来确定最终使用哪个路由进行处理,而不会依次调用所有匹配到的路由
1. 静态路由优先
静态路由(完全匹配的路径)优先级最高。例如,路径 /about 比路径 /about/{section} 有更高的优先级。
2. 参数数量少的优先
带参数的路径匹配时,参数数量少的优先。例如,路径 /user/{id} 比路径 /user/{id}/{action} 有更高的优先级。
3. 精确匹配优先
如果两个路径参数类型相同,则精确匹配的路径优先。例如,路径 /profile/{id:int} 比路径 /profile/{name:string} 有更高的优先级,因为 int 是更具体的匹配类型。
4. 路径长度优先
在参数数量和类型相同的情况下,路径较短的优先。例如,路径 /p/{short} 比路径 /profile/{long} 有更高的优先级。