> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arupa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 路由与传输

> 了解服务如何将自身的功能与 Arupa 应用连接起来。

服务通过两个相关的声明——传输和路由——将自己的功能暴露给应用的其余部分。理解它们之间的关系，有助于更好地阅读各个具体的[传输页面](./transport)。

## 传输：端点

传输是服务拥有的、能够处理流量的东西。每个传输都具有：

* 一个 **id**，由服务自行选择，在该服务内唯一；
* 一个 **类型**，为 `static`、`http` 或 `proxy` 之一；以及
* 特定于该类型的配置——例如，`static` 传输会指定它所服务的文件或目录，`proxy` 传输会指定它转发到的上游地址。

注册一个传输只是让这个端点存在，但并不会因此使其在某个 URL 或命名空间上可被访问。将其变得可访问是路由的职责。

## 路由：绑定

路由把一个 URL 模式连接到某个传输上，通过该传输的 id 来标识。路由具有：

* 一个 **id**，由服务自行选择，在该服务内唯一；
* 它所绑定的**传输 id**；以及
* 一个 HTTP 声明（`method`、`pattern`、`access`）。

HTTP 路由可以绑定到 `static`、`http` 或 `proxy` 传输——由该模式下应处理请求的传输决定。访问策略存在于路由上，而不是传输上，因此同一种传输类型的配置方式与谁能访问它无关；每条路由不同的地方在于*谁可以在哪个 URL 访问它*。

## 为什么要分开

把端点和绑定分开，可以让您：

* 让同一个传输在多条路由上暴露——例如，同一个静态文件来源可以通过两个不同的 URL 前缀访问；
* 在不重建底层连接的情况下更改指向某项功能的路径，这对 `proxy` 传输尤其重要，因为建立上游连接的开销相对较大；以及
* 独立地考虑所有权和清理问题：传输和路由是两个独立的注册表，只有内核被允许协调两者之间的关系。

## 注册与移除资源

`wasm` 或 `grpc` 服务可以在其运行期间的任意时刻注册和注销传输与路由，而不仅仅是在启动时——这在服务生命周期中的具体位置请参阅[协议](./protocol)。而 `static` 服务则是在其包清单中一次性、提前声明好自己的传输和路由；参阅 [Static 服务](./static-service)。

有几条规则是始终适用的：

* 当某个传输仍被某条路由引用时，不能移除该传输，必须先移除引用它的路由。
* 当一批路由被一起注册时，即使其中一些失败，成功的那些仍会保持注册状态；失败会使服务被标记为 `degraded`，而不会导致整批注册被拒绝。
* 当一个服务会话结束时——无论是进程退出、WASM 实例被卸载，还是服务通过管理 API 被停止——内核都会移除该服务的所有路由，然后再移除其所有传输，因此一个已经消亡的服务会话永远不会留下一个可访问但无主的绑定。

## 冲突

来自不同服务的路由共享同一片 URL 空间，因此内核会拒绝发生冲突的注册，而不是悄悄地用一个服务的路由覆盖另一个服务的路由：

* 同一个路径不能被两个不同的服务拥有，即使它们使用不同的 HTTP 方法也不行。
* 一个没有指定方法（匹配所有方法）的路由，会与同一路径下所有指定了具体方法的路由发生冲突。
* 由 `static` 传输支撑的路由与由非 static 传输支撑的路由，在同一路径上会发生冲突，即便它们的方法原本是兼容的——一个路径要么作为静态内容提供，要么被动态处理，不能两者兼具。

关于路径模式语言本身——精确匹配与子树匹配、根路径，以及如何选出最长匹配模式——请参阅[内核路由](../kernel/route)；关于每种传输类型对其路由有什么具体要求，请参阅各个传输专属页面。
