pub struct App<T> { /* private fields */ }
Expand description
Application builder - structure that follows the builder pattern for building application instances.
Implementations
sourceimpl<T> App<T>
impl<T> App<T>
sourcepub fn app_data<U: 'static>(self, ext: U) -> Self
pub fn app_data<U: 'static>(self, ext: U) -> Self
Set application (root level) data.
Application data stored with App::app_data()
method is available through the
HttpRequest::app_data
method at runtime.
Data<T>
Any Data<T>
type added here can utilize it’s extractor implementation in handlers.
Types not wrapped in Data<T>
cannot use this extractor. See its docs for more
about its usage and patterns.
use std::cell::Cell;
use actix_web::{web, App, HttpRequest, HttpResponse, Responder};
struct MyData {
count: std::cell::Cell<usize>,
}
async fn handler(req: HttpRequest, counter: web::Data<MyData>) -> impl Responder {
// note this cannot use the Data<T> extractor because it was not added with it
let incr = *req.app_data::<usize>().unwrap();
assert_eq!(incr, 3);
// update counter using other value from app data
counter.count.set(counter.count.get() + incr);
HttpResponse::Ok().body(counter.count.get().to_string())
}
let app = App::new().service(
web::resource("/")
.app_data(3usize)
.app_data(web::Data::new(MyData { count: Default::default() }))
.route(web::get().to(handler))
);
Shared Mutable State
HttpServer::new
accepts an application factory rather than an
application instance; the factory closure is called on each worker thread independently.
Therefore, if you want to share a data object between different workers, a shareable object
needs to be created first, outside the HttpServer::new
closure and cloned into it.
Data<T>
is an example of such a sharable object.
let counter = web::Data::new(AppStateWithCounter {
counter: Mutex::new(0),
});
HttpServer::new(move || {
// move counter object into the closure and clone for each worker
App::new()
.app_data(counter.clone())
.route("/", web::get().to(handler))
})
sourcepub fn data<U: 'static>(self, data: U) -> Self
👎 Deprecated since 4.0.0: Use .app_data(Data::new(val))
instead.
pub fn data<U: 'static>(self, data: U) -> Self
Use .app_data(Data::new(val))
instead.
Add application (root) data after wrapping in Data<T>
.
Deprecated in favor of app_data
.
sourcepub fn data_factory<F, Out, D, E>(self, data: F) -> Self where
F: Fn() -> Out + 'static,
Out: Future<Output = Result<D, E>> + 'static,
D: 'static,
E: Debug,
pub fn data_factory<F, Out, D, E>(self, data: F) -> Self where
F: Fn() -> Out + 'static,
Out: Future<Output = Result<D, E>> + 'static,
D: 'static,
E: Debug,
Add application data factory. This function is similar to .data()
but it accepts a
“data factory”. Data values are constructed asynchronously during application
initialization, before the server starts accepting requests.
sourcepub fn configure<F>(self, f: F) -> Self where
F: FnOnce(&mut ServiceConfig),
pub fn configure<F>(self, f: F) -> Self where
F: FnOnce(&mut ServiceConfig),
Run external configuration as part of the application building process
This function is useful for moving parts of configuration to a different module or even library. For example, some of the resource’s configuration could be moved to different module.
use actix_web::{web, App, HttpResponse};
// this function could be located in different module
fn config(cfg: &mut web::ServiceConfig) {
cfg.service(web::resource("/test")
.route(web::get().to(|| HttpResponse::Ok()))
.route(web::head().to(|| HttpResponse::MethodNotAllowed()))
);
}
App::new()
.configure(config) // <- register resources
.route("/index.html", web::get().to(|| HttpResponse::Ok()));
sourcepub fn route(self, path: &str, route: Route) -> Self
pub fn route(self, path: &str, route: Route) -> Self
Configure route for a specific path.
This is a simplified version of the App::service()
method.
This method can be used multiple times with same path, in that case
multiple resources with one route would be registered for same resource path.
use actix_web::{web, App, HttpResponse};
async fn index(data: web::Path<(String, String)>) -> &'static str {
"Welcome!"
}
fn main() {
let app = App::new()
.route("/test1", web::get().to(index))
.route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()));
}
sourcepub fn service<F>(self, factory: F) -> Self where
F: HttpServiceFactory + 'static,
pub fn service<F>(self, factory: F) -> Self where
F: HttpServiceFactory + 'static,
Register HTTP service.
Http service is any type that implements HttpServiceFactory
trait.
Actix Web provides several services implementations:
- Resource is an entry in resource table which corresponds to requested URL.
- Scope is a set of resources with common root path.
- “StaticFiles” is a service for static files support
sourcepub fn default_service<F, U>(self, svc: F) -> Self where
F: IntoServiceFactory<U, ServiceRequest>,
U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error> + 'static,
U::InitError: Debug,
pub fn default_service<F, U>(self, svc: F) -> Self where
F: IntoServiceFactory<U, ServiceRequest>,
U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error> + 'static,
U::InitError: Debug,
Default service to be used if no matching resource could be found.
It is possible to use services like Resource
, Route
.
use actix_web::{web, App, HttpResponse};
async fn index() -> &'static str {
"Welcome!"
}
fn main() {
let app = App::new()
.service(
web::resource("/index.html").route(web::get().to(index)))
.default_service(
web::route().to(|| HttpResponse::NotFound()));
}
It is also possible to use static files as default service.
use actix_web::{web, App, HttpResponse};
fn main() {
let app = App::new()
.service(
web::resource("/index.html").to(|| HttpResponse::Ok()))
.default_service(
web::to(|| HttpResponse::NotFound())
);
}
sourcepub fn external_resource<N, U>(self, name: N, url: U) -> Self where
N: AsRef<str>,
U: AsRef<str>,
pub fn external_resource<N, U>(self, name: N, url: U) -> Self where
N: AsRef<str>,
U: AsRef<str>,
Register an external resource.
External resources are useful for URL generation purposes only
and are never considered for matching at request time. Calls to
HttpRequest::url_for()
will work as expected.
use actix_web::{web, App, HttpRequest, HttpResponse, Result};
async fn index(req: HttpRequest) -> Result<HttpResponse> {
let url = req.url_for("youtube", &["asdlkjqme"])?;
assert_eq!(url.as_str(), "https://youtube.com/watch/asdlkjqme");
Ok(HttpResponse::Ok().into())
}
fn main() {
let app = App::new()
.service(web::resource("/index.html").route(
web::get().to(index)))
.external_resource("youtube", "https://youtube.com/watch/{video_id}");
}
sourcepub fn wrap<M, B, B1>(
self,
mw: M
) -> App<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B1>, Error = Error, InitError = ()>> where
T: ServiceFactory<ServiceRequest, Response = ServiceResponse<B>, Error = Error, Config = (), InitError = ()>,
B: MessageBody,
M: Transform<T::Service, ServiceRequest, Response = ServiceResponse<B1>, Error = Error, InitError = ()>,
B1: MessageBody,
pub fn wrap<M, B, B1>(
self,
mw: M
) -> App<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B1>, Error = Error, InitError = ()>> where
T: ServiceFactory<ServiceRequest, Response = ServiceResponse<B>, Error = Error, Config = (), InitError = ()>,
B: MessageBody,
M: Transform<T::Service, ServiceRequest, Response = ServiceResponse<B1>, Error = Error, InitError = ()>,
B1: MessageBody,
Registers middleware, in the form of a middleware component (type), that runs during inbound and/or outbound processing in the request life-cycle (request -> response), modifying request/response as necessary, across all requests managed by the Application.
Use middleware when you need to read or modify every request or response in some way.
Notice that the keyword for registering middleware is wrap
. As you
register middleware using wrap
in the App builder, imagine wrapping
layers around an inner App. The first middleware layer exposed to a
Request is the outermost layer– the last registered in
the builder chain. Consequently, the first middleware registered
in the builder chain is the last to execute during request processing.
use actix_service::Service;
use actix_web::{middleware, web, App};
use actix_web::http::header::{CONTENT_TYPE, HeaderValue};
async fn index() -> &'static str {
"Welcome!"
}
fn main() {
let app = App::new()
.wrap(middleware::Logger::default())
.route("/index.html", web::get().to(index));
}
sourcepub fn wrap_fn<F, R, B, B1>(
self,
mw: F
) -> App<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B1>, Error = Error, InitError = ()>> where
T: ServiceFactory<ServiceRequest, Response = ServiceResponse<B>, Error = Error, Config = (), InitError = ()>,
B: MessageBody,
F: Fn(ServiceRequest, &T::Service) -> R + Clone,
R: Future<Output = Result<ServiceResponse<B1>, Error>>,
B1: MessageBody,
pub fn wrap_fn<F, R, B, B1>(
self,
mw: F
) -> App<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B1>, Error = Error, InitError = ()>> where
T: ServiceFactory<ServiceRequest, Response = ServiceResponse<B>, Error = Error, Config = (), InitError = ()>,
B: MessageBody,
F: Fn(ServiceRequest, &T::Service) -> R + Clone,
R: Future<Output = Result<ServiceResponse<B1>, Error>>,
B1: MessageBody,
Registers middleware, in the form of a closure, that runs during inbound and/or outbound processing in the request life-cycle (request -> response), modifying request/response as necessary, across all requests managed by the Application.
Use middleware when you need to read or modify every request or response in some way.
use actix_service::Service;
use actix_web::{web, App};
use actix_web::http::header::{CONTENT_TYPE, HeaderValue};
async fn index() -> &'static str {
"Welcome!"
}
fn main() {
let app = App::new()
.wrap_fn(|req, srv| {
let fut = srv.call(req);
async {
let mut res = fut.await?;
res.headers_mut().insert(
CONTENT_TYPE, HeaderValue::from_static("text/plain"),
);
Ok(res)
}
})
.route("/index.html", web::get().to(index));
}
Auto Trait Implementations
impl<T> !RefUnwindSafe for App<T>
impl<T> !Send for App<T>
impl<T> !Sync for App<T>
impl<T> Unpin for App<T> where
T: Unpin,
impl<T> !UnwindSafe for App<T>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> Instrument for T
impl<T> Instrument for T
sourcefn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
sourcefn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
sourceimpl<T> WithSubscriber for T
impl<T> WithSubscriber for T
sourcefn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
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
sourcefn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
Attaches the current default Subscriber
to this type, returning a
WithDispatch
wrapper. Read more