Skip to main content

RequestContext

Struct RequestContext 

Source
pub struct RequestContext;
Expand description

Scoped identity and trace id of the current request, shared by every layer.

This is the single source of truth for “who is acting” and “which request is this”. The HTTP adapter establishes the context before binding the request (RequestModel::bind), so the binder, the handler, middleware and the persistence layer all read the very same Arc<IdentityUser> and the very same trace id — there is no second copy of sub and no way for audit and handler code to disagree.

The trace id is the one the tracing middleware echoes in the x-trace-id response header, so a handler that stamps it onto an audit row can be joined with the access log line for the same request:

ⓘ
let trace_id = RequestContext::trace_id().map(|id| id.to_string());
audit.trace_id = trace_id;

Background work (IHostedService, spawned tasks, timers) has no ambient identity by default: identity() and operator_id() return None there, which audit code must treat as the System principal. A background job that acts on behalf of a user scopes that identity explicitly:

ⓘ
let identity = Arc::new(IdentityUser { id: "user-1".into(), ..Default::default() });
RequestContext::run(Some(identity), async move {
    // audit here sees user-1
})
.await;

Implementations§

Source§

impl RequestContext

Source

pub async fn run<F, R>(identity: Option<Arc<IdentityUser>>, f: F) -> R
where F: Future<Output = R>,

Run an async block with identity in scope.

Pass None for an anonymous request (or a system-initiated task); inside f, identity() and operator_id() then return None.

An enclosing trace id is preserved: nesting a narrower identity scope (audit helpers do this) must not make the trace id disappear.

Source

pub async fn run_with_trace<F, R>( identity: Option<Arc<IdentityUser>>, trace_id: Option<Arc<str>>, f: F, ) -> R
where F: Future<Output = R>,

Run an async block with identity and trace_id in scope.

The HTTP adapter uses this: it passes the context’s IHttpContext::trace_id so the handler reads exactly the id emitted in the x-trace-id response header. Pass None for a request that has no trace id.

Source

pub fn identity() -> Option<Arc<IdentityUser>>

The authenticated identity of the current request, if any.

Returns the very Arc the HTTP adapter created, so resolving the identity twice never allocates a second copy.

Source

pub fn trace_id() -> Option<Arc<str>>

The trace id of the current request, if the host assigned one.

Identical to the x-trace-id response header. None outside a request scope (background work) and for hosts that do not run the tracing middleware.

Source

pub fn operator_id() -> Option<String>

The current operator id (IdentityUser::id), if authenticated.

None for anonymous requests and for background work that did not scope an identity — audit code should record those as System.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more