Skip to main content

openapp_sdk_core/
interceptor.rs

1//! Request / response interceptors.
2//!
3//! A light wrapper that lets callers observe or mutate outgoing requests
4//! (logging, tracing span injection, custom headers, tenant pinning) without
5//! re-implementing the transport.
6//!
7//! The default client installs only the built-in telemetry interceptor. Additional
8//! interceptors are appended via [`crate::ClientBuilder::interceptor`] and run in the
9//! order they were added.
10
11use std::sync::Arc;
12
13use async_trait::async_trait;
14use reqwest::{Request, Response};
15
16use crate::error::SdkError;
17
18/// Hook invoked around every outgoing HTTP request.
19#[async_trait]
20pub trait Interceptor: Send + Sync + std::fmt::Debug {
21    /// Called just before the request is dispatched. Implementations may mutate the
22    /// request (add headers, extend the URL) by returning a modified [`Request`].
23    async fn on_request(&self, request: Request) -> Result<Request, SdkError> {
24        Ok(request)
25    }
26
27    /// Called after the transport layer produced a response. Implementations are free
28    /// to observe the response; transforming it is not supported here on purpose —
29    /// retry/decode semantics belong to the core, not to arbitrary interceptors.
30    async fn on_response(&self, _response: &Response) -> Result<(), SdkError> {
31        Ok(())
32    }
33}
34
35/// Shared-ownership handle used throughout the SDK.
36pub type SharedInterceptor = Arc<dyn Interceptor>;
37
38/// Built-in interceptor that adds a structured [`tracing`] span around every request.
39#[derive(Debug, Default, Clone, Copy)]
40pub struct TracingInterceptor;
41
42#[async_trait]
43impl Interceptor for TracingInterceptor {
44    async fn on_request(&self, request: Request) -> Result<Request, SdkError> {
45        tracing::debug!(
46            method = %request.method(),
47            url = %request.url(),
48            "openapp-sdk: dispatching request"
49        );
50        Ok(request)
51    }
52
53    async fn on_response(&self, response: &Response) -> Result<(), SdkError> {
54        tracing::debug!(
55            status = response.status().as_u16(),
56            url = %response.url(),
57            "openapp-sdk: received response"
58        );
59        Ok(())
60    }
61}