build: echo request id response header
This commit is contained in:
@@ -102,7 +102,8 @@
|
||||
交付物:[../server-rs/apps/api-server/src/http_error.rs](../server-rs/apps/api-server/src/http_error.rs)、[../server-rs/apps/api-server/src/error_middleware.rs](../server-rs/apps/api-server/src/error_middleware.rs)、[../server-rs/apps/api-server/src/app.rs](../server-rs/apps/api-server/src/app.rs)
|
||||
- [x] 接入当前项目兼容的 response envelope
|
||||
交付物:[../server-rs/apps/api-server/src/api_response.rs](../server-rs/apps/api-server/src/api_response.rs)、[../server-rs/apps/api-server/src/request_context.rs](../server-rs/apps/api-server/src/request_context.rs)、[../server-rs/apps/api-server/src/http_error.rs](../server-rs/apps/api-server/src/http_error.rs)
|
||||
- [ ] 接入 `x-request-id`
|
||||
- [x] 接入 `x-request-id`
|
||||
交付物:[../server-rs/apps/api-server/src/response_headers.rs](../server-rs/apps/api-server/src/response_headers.rs)、[../server-rs/apps/api-server/src/app.rs](../server-rs/apps/api-server/src/app.rs)
|
||||
- [ ] 接入 `x-api-version`
|
||||
- [ ] 接入 `x-route-version`
|
||||
- [ ] 接入 `x-response-time-ms`
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
1. 中间件优先读取来访 `x-request-id`,未提供时生成新的 UUID。
|
||||
2. `request_id` 会统一写入请求 `extensions` 与请求头,供 tracing、错误处理中间件和响应头层复用。
|
||||
3. 响应头回写 `x-request-id` 仍属于后续独立任务,本阶段只完成请求上下文准备。
|
||||
3. 最终响应会回写同一个 `x-request-id`,保证调用方、日志链路和后续 envelope `meta.requestId` 可对齐。
|
||||
|
||||
当前错误处理中间件约定:
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ use tracing::{info_span, Level};
|
||||
use crate::{
|
||||
error_middleware::normalize_error_response,
|
||||
request_context::{attach_request_context, resolve_request_id},
|
||||
response_headers::propagate_request_id_header,
|
||||
state::AppState,
|
||||
};
|
||||
|
||||
@@ -13,6 +14,8 @@ pub fn build_router(state: AppState) -> Router {
|
||||
Router::new()
|
||||
// 错误归一化层放在 tracing 里侧,让 tracing 记录到最终对外返回的状态与错误体形态。
|
||||
.layer(middleware::from_fn(normalize_error_response))
|
||||
// 响应头回写放在错误归一化外侧,确保最终写回的是归一化后的最终响应。
|
||||
.layer(middleware::from_fn(propagate_request_id_header))
|
||||
// 当前阶段先统一挂接 HTTP tracing,后续 request_id、响应头与错误中间件继续在这里扩展。
|
||||
.layer(
|
||||
TraceLayer::new_for_http()
|
||||
|
||||
@@ -5,6 +5,7 @@ mod error_middleware;
|
||||
mod http_error;
|
||||
mod logging;
|
||||
mod request_context;
|
||||
mod response_headers;
|
||||
mod state;
|
||||
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
23
server-rs/apps/api-server/src/response_headers.rs
Normal file
23
server-rs/apps/api-server/src/response_headers.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use axum::{
|
||||
extract::Request,
|
||||
http::{header::HeaderName, HeaderValue},
|
||||
middleware::Next,
|
||||
response::Response,
|
||||
};
|
||||
|
||||
use crate::request_context::{resolve_request_id, X_REQUEST_ID_HEADER};
|
||||
|
||||
pub async fn propagate_request_id_header(request: Request, next: Next) -> Response {
|
||||
let request_id = resolve_request_id(&request);
|
||||
let mut response = next.run(request).await;
|
||||
|
||||
if let Some(request_id) = request_id {
|
||||
if let Ok(header_value) = HeaderValue::from_str(&request_id) {
|
||||
response
|
||||
.headers_mut()
|
||||
.insert(HeaderName::from_static(X_REQUEST_ID_HEADER), header_value);
|
||||
}
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
Reference in New Issue
Block a user