diff --git a/backend-rewrite-tasklist/01_M0_M2_FOUNDATION_AND_AUTH.md b/backend-rewrite-tasklist/01_M0_M2_FOUNDATION_AND_AUTH.md index 3e1453bd..487d8e50 100644 --- a/backend-rewrite-tasklist/01_M0_M2_FOUNDATION_AND_AUTH.md +++ b/backend-rewrite-tasklist/01_M0_M2_FOUNDATION_AND_AUTH.md @@ -108,7 +108,8 @@ 交付物:[../server-rs/apps/api-server/src/response_headers.rs](../server-rs/apps/api-server/src/response_headers.rs) - [x] 接入 `x-route-version` 交付物:[../server-rs/apps/api-server/src/response_headers.rs](../server-rs/apps/api-server/src/response_headers.rs) -- [ ] 接入 `x-response-time-ms` +- [x] 接入 `x-response-time-ms` + 交付物:[../server-rs/apps/api-server/src/response_headers.rs](../server-rs/apps/api-server/src/response_headers.rs)、[../server-rs/apps/api-server/src/request_context.rs](../server-rs/apps/api-server/src/request_context.rs) - [ ] 实现 `/healthz` ### 基础工程脚本 diff --git a/server-rs/apps/api-server/README.md b/server-rs/apps/api-server/README.md index 4f7eba34..ddf43069 100644 --- a/server-rs/apps/api-server/README.md +++ b/server-rs/apps/api-server/README.md @@ -62,7 +62,7 @@ 1. 所有响应都会回写 `x-request-id`。 2. 所有响应都会回写固定的 `x-api-version`,当前值与 body `meta.apiVersion` 保持一致。 3. 所有响应都会回写 `x-route-version`,当前阶段默认与 `x-api-version` 保持一致,后续再按路由粒度细分。 -4. `x-response-time-ms` 仍留在后续独立任务中补齐。 +4. 所有响应都会回写 `x-response-time-ms`,值来源于 `RequestContext` 内记录的请求开始时间。 ## 3. 边界约束 diff --git a/server-rs/apps/api-server/src/response_headers.rs b/server-rs/apps/api-server/src/response_headers.rs index fceb8f12..34935db1 100644 --- a/server-rs/apps/api-server/src/response_headers.rs +++ b/server-rs/apps/api-server/src/response_headers.rs @@ -7,14 +7,16 @@ use axum::{ use crate::{ api_response::API_VERSION, - request_context::{resolve_request_id, X_REQUEST_ID_HEADER}, + request_context::{resolve_request_id, RequestContext, X_REQUEST_ID_HEADER}, }; pub const API_VERSION_HEADER: &str = "x-api-version"; +pub const RESPONSE_TIME_HEADER: &str = "x-response-time-ms"; pub const ROUTE_VERSION_HEADER: &str = "x-route-version"; pub async fn propagate_request_id_header(request: Request, next: Next) -> Response { let request_id = resolve_request_id(&request); + let request_context = request.extensions().get::().cloned(); let mut response = next.run(request).await; if let Some(request_id) = request_id { @@ -37,5 +39,13 @@ pub async fn propagate_request_id_header(request: Request, next: Next) -> Respon .insert(HeaderName::from_static(ROUTE_VERSION_HEADER), header_value); } + if let Some(request_context) = request_context { + if let Ok(header_value) = HeaderValue::from_str(&request_context.elapsed().to_string()) { + response + .headers_mut() + .insert(HeaderName::from_static(RESPONSE_TIME_HEADER), header_value); + } + } + response }