1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-28 01:52:57 +01:00
actix-web/src/web.rs

181 lines
5.4 KiB
Rust
Raw Normal View History

2019-03-30 18:04:38 +01:00
//! Essentials helper functions and types for application registration.
2021-02-10 13:10:03 +01:00
2020-05-18 04:47:20 +02:00
use std::future::Future;
2019-03-30 18:04:38 +01:00
2021-08-06 23:42:31 +02:00
use actix_http::http::Method;
use actix_router::IntoPatterns;
pub use bytes::{Buf, BufMut, Bytes, BytesMut};
2019-03-30 18:04:38 +01:00
2021-09-03 19:00:43 +02:00
use crate::{
error::BlockingError, extract::FromRequest, handler::Handler, resource::Resource,
responder::Responder, route::Route, scope::Scope, service::WebService,
};
2019-03-30 18:04:38 +01:00
2019-04-15 16:32:49 +02:00
pub use crate::config::ServiceConfig;
pub use crate::data::Data;
2019-03-30 18:04:38 +01:00
pub use crate::request::HttpRequest;
pub use crate::request_data::ReqData;
2021-09-03 19:00:43 +02:00
pub use crate::response::HttpResponse;
2019-03-30 18:04:38 +01:00
pub use crate::types::*;
2021-09-03 19:00:43 +02:00
/// Creates a new resource for a specific path.
2019-03-30 18:04:38 +01:00
///
2021-09-03 19:00:43 +02:00
/// Resources may have dynamic path segments. For example, a resource with the path `/a/{name}/c`
/// would match all incoming requests with paths such as `/a/b/c`, `/a/1/c`, or `/a/etc/c`.
2019-03-30 18:04:38 +01:00
///
2021-09-03 19:00:43 +02:00
/// A dynamic segment is specified in the form `{identifier}`, where the identifier can be used
/// later in a request handler to access the matched value for that segment. This is done by looking
/// up the identifier in the `Path` object returned by [`HttpRequest.match_info()`] method.
2019-03-30 18:04:38 +01:00
///
/// By default, each segment matches the regular expression `[^{}/]+`.
///
/// You can also specify a custom regex in the form `{identifier:regex}`:
///
2021-09-03 19:00:43 +02:00
/// For instance, to route `GET`-requests on any route matching `/users/{userid}/{friend}` and store
/// `userid` and `friend` in the exposed `Path` object:
2019-03-30 18:04:38 +01:00
///
/// ```
2019-03-30 18:04:38 +01:00
/// use actix_web::{web, App, HttpResponse};
///
2019-12-08 07:31:16 +01:00
/// let app = App::new().service(
/// web::resource("/users/{userid}/{friend}")
/// .route(web::get().to(|| HttpResponse::Ok()))
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
/// );
2019-03-30 18:04:38 +01:00
/// ```
2021-08-06 23:42:31 +02:00
pub fn resource<T: IntoPatterns>(path: T) -> Resource {
2019-03-30 18:04:38 +01:00
Resource::new(path)
}
2021-09-03 19:00:43 +02:00
/// Creates scope for common path prefix.
2019-03-30 18:04:38 +01:00
///
2021-09-03 19:00:43 +02:00
/// Scopes collect multiple paths under a common path prefix. The scope's path can contain dynamic
/// path segments.
///
/// # Examples
/// In this example, three routes are set up (and will handle any method):
/// * `/{project_id}/path1`
/// * `/{project_id}/path2`
/// * `/{project_id}/path3`
2019-03-30 18:04:38 +01:00
///
/// ```
2019-03-30 18:04:38 +01:00
/// use actix_web::{web, App, HttpResponse};
///
2019-12-08 07:31:16 +01:00
/// let app = App::new().service(
/// web::scope("/{project_id}")
/// .service(web::resource("/path1").to(|| HttpResponse::Ok()))
/// .service(web::resource("/path2").to(|| HttpResponse::Ok()))
/// .service(web::resource("/path3").to(|| HttpResponse::MethodNotAllowed()))
/// );
2019-03-30 18:04:38 +01:00
/// ```
pub fn scope(path: &str) -> Scope {
2019-03-30 18:04:38 +01:00
Scope::new(path)
}
2021-09-03 19:00:43 +02:00
/// Creates a new un-configured route.
pub fn route() -> Route {
2019-03-30 18:04:38 +01:00
Route::new()
}
2021-09-03 19:00:43 +02:00
macro_rules! method_route {
($method_fn:ident, $method_const:ident) => {
paste::paste! {
2021-09-08 18:42:14 +02:00
#[doc = " Creates a new route with `" $method_const "` method guard."]
2021-09-03 19:00:43 +02:00
///
/// # Examples
2021-09-08 18:42:14 +02:00
#[doc = " In this example, one `" $method_const " /{project_id}` route is set up:"]
2021-09-03 19:00:43 +02:00
/// ```
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
/// web::resource("/{project_id}")
#[doc = " .route(web::" $method_fn "().to(|| HttpResponse::Ok()))"]
///
/// );
/// ```
pub fn $method_fn() -> Route {
method(Method::$method_const)
}
}
};
2019-03-30 18:04:38 +01:00
}
2021-09-03 19:00:43 +02:00
method_route!(get, GET);
method_route!(post, POST);
method_route!(put, PUT);
method_route!(patch, PATCH);
method_route!(delete, DELETE);
method_route!(head, HEAD);
method_route!(trace, TRACE);
2019-03-30 18:04:38 +01:00
2021-09-03 19:00:43 +02:00
/// Creates a new route with specified method guard.
2019-03-30 18:04:38 +01:00
///
2021-09-03 19:00:43 +02:00
/// # Examples
/// In this example, one `GET /{project_id}` route is set up:
2019-03-30 18:04:38 +01:00
///
/// ```
2019-03-30 18:04:38 +01:00
/// use actix_web::{web, http, App, HttpResponse};
///
2019-12-08 07:31:16 +01:00
/// let app = App::new().service(
/// web::resource("/{project_id}")
/// .route(web::method(http::Method::GET).to(|| HttpResponse::Ok()))
/// );
2019-03-30 18:04:38 +01:00
/// ```
pub fn method(method: Method) -> Route {
2019-03-30 18:04:38 +01:00
Route::new().method(method)
}
2021-09-03 19:00:43 +02:00
/// Creates a new any-method route with handler.
2019-03-30 18:04:38 +01:00
///
/// ```
2019-11-21 16:34:04 +01:00
/// use actix_web::{web, App, HttpResponse, Responder};
2019-03-30 18:04:38 +01:00
///
2019-11-21 16:34:04 +01:00
/// async fn index() -> impl Responder {
/// HttpResponse::Ok()
2019-03-30 18:04:38 +01:00
/// }
///
/// App::new().service(
/// web::resource("/").route(
/// web::to(index))
/// );
/// ```
2020-12-26 22:46:19 +01:00
pub fn to<F, I, R>(handler: F) -> Route
2019-03-30 18:04:38 +01:00
where
2020-12-26 22:46:19 +01:00
F: Handler<I, R>,
I: FromRequest + 'static,
2020-12-26 22:46:19 +01:00
R: Future + 'static,
R::Output: Responder + 'static,
2019-03-30 18:04:38 +01:00
{
2019-11-21 16:34:04 +01:00
Route::new().to(handler)
2019-03-30 18:04:38 +01:00
}
2021-09-03 19:00:43 +02:00
/// Creates a raw service for a specific path.
2019-04-25 00:29:15 +02:00
///
/// ```
2019-11-20 18:33:22 +01:00
/// use actix_web::{dev, web, guard, App, Error, HttpResponse};
2019-04-25 00:29:15 +02:00
///
2019-11-21 10:56:49 +01:00
/// async fn my_service(req: dev::ServiceRequest) -> Result<dev::ServiceResponse, Error> {
/// Ok(req.into_response(HttpResponse::Ok().finish()))
2019-04-25 00:29:15 +02:00
/// }
///
2019-12-08 07:31:16 +01:00
/// let app = App::new().service(
/// web::service("/users/*")
/// .guard(guard::Header("content-type", "text/plain"))
/// .finish(my_service)
/// );
2019-04-25 00:29:15 +02:00
/// ```
2021-08-06 23:42:31 +02:00
pub fn service<T: IntoPatterns>(path: T) -> WebService {
2019-04-25 00:29:15 +02:00
WebService::new(path)
}
2021-09-03 19:00:43 +02:00
/// Executes blocking function on a thread pool, returns future that resolves to result of the
/// function execution.
pub fn block<F, R>(f: F) -> impl Future<Output = Result<R, BlockingError>>
2019-03-30 18:04:38 +01:00
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
2019-03-30 18:04:38 +01:00
{
let fut = actix_rt::task::spawn_blocking(f);
async { fut.await.map_err(|_| BlockingError) }
2019-03-30 18:04:38 +01:00
}