中间件
使用中间件
在 Volo-HTTP 中, 中间件一般是作为 Layer
实现的, Volo-HTTP 中也有一些内置的中间件,
比如我们使用内置的 TimeoutLayer
:
编写一个中间件
在 Volo-HTTP 中, 也提供了一些便于实现中间件的功能, 如 from_fn
和 map_response
。
两者都可以接收一个函数来作为中间件,不过区别是,
from_fn
接收 Request 并返回 Response, 在其函数中可以调用内层服务, 也可以直接返回 Responsemap_response
作用于 Response, 接收 Response 并返回处理过的 Response
from_fn
from_fn
使用的函数可以通过 extractor 提取特定类型的参数,
但最后一定要附加 cx
, req
和 next
这三个参数,并通过 next.run(cx, req).await
来调用内层的服务。
这里我们以 from_fn
为例,实现一个用于记录单个请求耗时的中间件:
或者也可以对特定请求提前返回, 比如我们实现一个缺德的中间件,有 50% 的几率会拒绝当前的请求:
这种形式可以用于鉴权等场景, 如果请求不允许被访问该服务, 可以直接返回一个特定的 Response, 而无需执行后续的 Service。
map_response
map_response
作用于 Response, 接收 Response 并返回处理过的 Response
这种方式可以对 Response 进行一些通用逻辑的处理,比如追加跨域相关的 headers 或者设置 Cookies 等
由于我们为以下类型实现了 IntoResponse
这个 trait:
((HeaderName, HeaderValue), Response)
([(HeaderName, HeaderValue); N], Response
)
可以在 map_response
中借助以下形式方便地实现为 Response 追加 headers 等功能:
注意到 append_header(s)
的返回值类型是 impl IntoResponse
其实这两个函数的返回值类型分别是:
((&'static str, &'static str), ServerResponse)
([(&'static str, &'static str); 3], ServerResponse)
但是这两个类型写起来比较麻烦, 所以可以直接使用 impl IntoResponse
的方式实现, 只要保证返回值类型实现了 IntoResponse
即可
需要注意的是,即使返回值类型直接写了 impl IntoResponse
, 但也需要保证函数中的返回值是同一个类型,
因为使用这种方式也需要一个特定类型的返回值, 只是我们将这个工作交给编译器来推导了。