pub struct Data<T: ?Sized>(/* private fields */);
Expand description
Application data wrapper and extractor.
§Setting Data
Data is set using the app_data
methods on App
, Scope
, and Resource
. If data is wrapped
in this Data
type for those calls, it can be used as an extractor.
Note that Data
should be constructed outside the HttpServer::new
closure if shared,
potentially mutable state is desired. Data
is cheap to clone; internally, it uses an Arc
.
See also App::app_data
, Scope::app_data
,
and Resource::app_data
.
§Extracting Data
Since the Actix Web router layers application data, the returned object will reference the
“closest” instance of the type. For example, if an App
stores a u32
, a nested Scope
also stores a u32
, and the delegated request handler falls within that Scope
, then
extracting a web::Data<u32>
for that handler will return the Scope
’s instance. However,
using the same router set up and a request that does not get captured by the Scope
,
web::<Data<u32>>
would return the App
’s instance.
If route data is not set for a handler, using Data<T>
extractor would cause a 500 Internal Server Error
response.
See also HttpRequest::app_data
and ServiceRequest::app_data
.
§Unsized Data
For types that are unsized, most commonly dyn T
, Data
can wrap these types by first
constructing an Arc<dyn T>
and using the From
implementation to convert it.
let displayable_arc: Arc<dyn Display> = Arc::new(42usize);
let displayable_data: Data<dyn Display> = Data::from(displayable_arc);
§Examples
use std::sync::Mutex;
use actix_web::{App, HttpRequest, HttpResponse, Responder, web::{self, Data}};
struct MyData {
counter: usize,
}
/// Use the `Data<T>` extractor to access data in a handler.
async fn index(data: Data<Mutex<MyData>>) -> impl Responder {
let mut my_data = data.lock().unwrap();
my_data.counter += 1;
HttpResponse::Ok()
}
/// Alternatively, use the `HttpRequest::app_data` method to access data in a handler.
async fn index_alt(req: HttpRequest) -> impl Responder {
let data = req.app_data::<Data<Mutex<MyData>>>().unwrap();
let mut my_data = data.lock().unwrap();
my_data.counter += 1;
HttpResponse::Ok()
}
let data = Data::new(Mutex::new(MyData { counter: 0 }));
let app = App::new()
// Store `MyData` in application storage.
.app_data(Data::clone(&data))
.route("/index.html", web::get().to(index))
.route("/index-alt.html", web::get().to(index_alt));
Implementations§
Trait Implementations§
source§impl<'de, T> Deserialize<'de> for Data<T>where
T: Deserialize<'de>,
impl<'de, T> Deserialize<'de> for Data<T>where
T: Deserialize<'de>,
source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
source§impl<T: ?Sized + 'static> FromRequest for Data<T>
impl<T: ?Sized + 'static> FromRequest for Data<T>
source§fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future
Self
from request parts asynchronously.