pub struct App<T> { /* private fields */ }
Expand description
The top-level builder for an Actix Web application.
Implementations§
source§impl<T> App<T>
impl<T> App<T>
sourcepub fn app_data<U: 'static>(self, data: U) -> Self
pub fn app_data<U: 'static>(self, data: 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 its 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
.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
pub fn data_factory<F, Out, D, E>(self, data: F) -> Self
Add application data factory that resolves asynchronously.
Data items are constructed during application initialization, before the server starts accepting requests.
The returned data value D
is wrapped as Data<D>
.
sourcepub fn configure<F>(self, f: F) -> Selfwhere
F: FnOnce(&mut ServiceConfig),
pub fn configure<F>(self, f: F) -> Selfwhere
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!"
}
let app = App::new()
.route("/test1", web::get().to(index))
.route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()));
sourcepub fn service<F>(self, factory: F) -> Selfwhere
F: HttpServiceFactory + 'static,
pub fn service<F>(self, factory: F) -> Selfwhere
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.
sourcepub fn default_service<F, U>(self, svc: F) -> Selfwhere
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) -> Selfwhere
F: IntoServiceFactory<U, ServiceRequest>,
U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error> + 'static,
U::InitError: Debug,
Default service that is invoked when no matching resource could be found.
You can use a Route
as default service.
If a default service is not registered, an empty 404 Not Found
response will be sent to
the client instead.
§Examples
use actix_web::{web, App, HttpResponse};
async fn index() -> &'static str {
"Welcome!"
}
let app = App::new()
.service(web::resource("/index.html").route(web::get().to(index)))
.default_service(web::to(|| HttpResponse::NotFound()));
sourcepub fn external_resource<N, U>(self, name: N, url: U) -> Self
pub fn external_resource<N, U>(self, name: N, url: U) -> Self
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())
}
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>(
self,
mw: M,
) -> App<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>>where
M: Transform<T::Service, ServiceRequest, Response = ServiceResponse<B>, Error = Error, InitError = ()> + 'static,
B: MessageBody,
pub fn wrap<M, B>(
self,
mw: M,
) -> App<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>>where
M: Transform<T::Service, ServiceRequest, Response = ServiceResponse<B>, Error = Error, InitError = ()> + 'static,
B: MessageBody,
Registers an app-wide middleware.
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 App
.
Use middleware when you need to read or modify every request or response in some way.
Middleware can be applied similarly to individual Scope
s and Resource
s.
See Scope::wrap
and Resource::wrap
.
For more info on middleware take a look at the middleware
module.
§Examples
use actix_web::{middleware, web, App};
async fn index() -> &'static str {
"Welcome!"
}
let app = App::new()
.wrap(middleware::Logger::default())
.route("/index.html", web::get().to(index));
sourcepub fn wrap_fn<F, R, B>(
self,
mw: F,
) -> App<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>>where
F: Fn(ServiceRequest, &T::Service) -> R + Clone + 'static,
R: Future<Output = Result<ServiceResponse<B>, Error>>,
B: MessageBody,
pub fn wrap_fn<F, R, B>(
self,
mw: F,
) -> App<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>>where
F: Fn(ServiceRequest, &T::Service) -> R + Clone + 'static,
R: Future<Output = Result<ServiceResponse<B>, Error>>,
B: MessageBody,
Registers an app-wide function middleware.
mw
is 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 handled by the App
.
Use middleware when you need to read or modify every request or response in some way.
Middleware can also be applied to individual Scope
s and Resource
s.
See App::wrap
for details on how middlewares compose with each other.
§Examples
use actix_web::{dev::Service as _, middleware, web, App};
use actix_web::http::header::{CONTENT_TYPE, HeaderValue};
async fn index() -> &'static str {
"Welcome!"
}
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));