Skip to main content

aiway_protocol/context/
route.rs

1use crate::gateway::plugin::ConfiguredPlugin;
2use serde::{Deserialize, Serialize};
3use std::collections::BTreeMap;
4
5#[derive(Debug, Clone, Default, Serialize, Deserialize)]
6pub struct Route {
7    /// 路由名称
8    pub name: String,
9    /// Host,可选,`*` 代表不限制。
10    /// 支持泛域名,格式为 `*.example.com`,通配符只能出现在域名开头。
11    pub host: String,
12    /// 路径,支持通配符,必须以 `/` 开头,全局唯一。
13    /// 同一域名下的路径不能存在冲突,如 `/api/*` 和 `/api/**` 就是冲突的路径,在控制台保存时需要校验。
14    /// 所有为 `*` 的域名下的路径也不能冲突。
15    pub path: String,
16    /// 转换后的匹配路径。
17    /// 由于路径匹配组件使用的是`matchit`,格式为`/xxx/{*any}`,
18    /// 它不符合常用的`/api/**`的格式,而`path`储存的是常用格式,
19    /// 所以这里需要做一次转换。
20    pub match_paths: Vec<String>,
21    /// 需要路由到的服务ID,例如 `user-service`
22    pub service: String,
23    /// 请求方法:GET | POST | PUT | DELETE | PATCH | OPTIONS | HEAD
24    /// 支持配置多个。当为空数组时表示不限制。
25    /// 不参与路由唯一性验证。
26    pub methods: Vec<String>,
27    /// header匹配条件。
28    /// 当存在多个时,所有条件都匹配时才算匹配成功。
29    /// 不参与路由唯一性验证。
30    #[serde(alias = "header_condition", alias = "header-condition")]
31    pub header: BTreeMap<String, String>,
32    /// query匹配条件
33    /// 当存在多个时,所有条件都匹配时才算匹配成功。
34    /// 不参与路由唯一性验证。
35    #[serde(alias = "query_condition", alias = "query-condition")]
36    pub query: BTreeMap<String, String>,
37    /// 插件
38    #[serde(default = "Vec::default", alias = "pre_filters", alias = "pre-filters")]
39    pub plugins: Vec<ConfiguredPlugin>,
40    /// 是否开启鉴权。
41    /// 启用后,需要在控制台的“密钥管理”处创建API Key,
42    /// 并通过请求头 `X-Aiway-Authorization` 传入,作为网关的鉴权凭证。
43    #[serde(default = "bool::default", alias = "is_auth", alias = "is-auth")]
44    pub is_auth: bool,
45    /// 鉴权路径白名单
46    pub auth_white_list: Vec<String>,
47}
48
49impl Route {
50    pub fn get_service(&self) -> &String {
51        &self.service
52    }
53
54    /// host + path作为匹配的key
55    pub fn to_match_keys(&self) -> Vec<String> {
56        self.match_paths
57            .iter()
58            .map(|p| {
59                if self.host == "*" {
60                    format!("{{host}}{}", p)
61                } else {
62                    format!("{}{}", self.host, p)
63                }
64            })
65            .collect()
66    }
67}