From 71e6f076a4a838e7dcc3827769a2417295979d35 Mon Sep 17 00:00:00 2001 From: Cameron Dershem Date: Mon, 17 Jun 2019 04:12:11 -0400 Subject: [PATCH] First pass at url-dispatch chapter. --- content/docs/url-dispatch.md | 74 ++++++++++++--------------- examples/url-dispatch/src/cfg.rs | 2 +- examples/url-dispatch/src/main.rs | 2 +- examples/url-dispatch/src/minfo.rs | 11 ++-- examples/url-dispatch/src/path2.rs | 2 +- examples/url-dispatch/src/resource.rs | 2 +- examples/url-dispatch/src/url_ext.rs | 16 +++--- examples/url-dispatch/src/urls.rs | 2 +- 8 files changed, 54 insertions(+), 57 deletions(-) diff --git a/content/docs/url-dispatch.md b/content/docs/url-dispatch.md index cef0595..8edce57 100644 --- a/content/docs/url-dispatch.md +++ b/content/docs/url-dispatch.md @@ -6,7 +6,7 @@ weight: 190 # URL Dispatch -URL dispatch provides a simple way for mapping URLs to `Handler` code using a simple pattern +URL dispatch provides a simple way for mapping URLs to handler code using a simple pattern matching language. If one of the patterns matches the path information associated with a request, a particular handler object is invoked. @@ -75,23 +75,21 @@ If a resource can not match any route, a "NOT FOUND" response is returned. [*Route*](../../actix-web/actix_web/dev/struct.Route.html) object. Route can be configured with a builder-like pattern. Following configuration methods are available: -* [*Route::filter()*](../../actix-web/actix_web/dev/struct.Route.html#method.filter) - registers a new predicate. Any number of predicates can be registered for each route. -* [*Route::f()*](../../actix-web/actix_web/dev/struct.Route.html#method.f) registers +* [*Route::guard()*](../../actix-web/actix_web/dev/struct.Route.html#method.guard) + registers a new guard. Any number of guards can be registered for each route. +* [*Route::method()*](../../actix-web/actix_web/dev/struct.Route.html#method.method) + registers a method guard. Any number of guards can be registered for each route. +* [*Route::to()*](../../actix-web/actix_web/dev/struct.Route.html#method.to) registers handler function for this route. Only one handler can be registered. Usually handler registration is the last config operation. Handler function can be a function or closure and has the type - `Fn(&HttpRequest) -> R + 'static` -* [*Route::h()*](../../actix-web/actix_web/dev/struct.Route.html#method.h) registers - a handler object that implements the `Handler` trait. This is - similar to `f()` method - only one handler can - be registered. Handler registration is the last config operation. -* [*Route::a()*](../../actix-web/actix_web/dev/struct.Route.html#method.a) registers + `Fn(HttpRequest) -> R + 'static` +* [*Route::to_async()*](../../actix-web/actix_web/dev/struct.Route.html#method.to_async) registers an async handler function for this route. Only one handler can be registered. Handler registration is the last config operation. Handler function can be a function or closure and has the type - `Fn(&HttpRequest) -> Future + 'static` + `Fn(HttpRequest) -> Future + 'static` # Route matching @@ -104,14 +102,15 @@ the request's path against the pattern declared. This checking happens in the or the routes were declared via `App::resource()` method. If resource can not be found, the *default resource* is used as the matched resource. -When a route configuration is declared, it may contain route predicate arguments. All route -predicates associated with a route declaration must be `true` for the route configuration to -be used for a given request during a check. If any predicate in the set of route predicate +When a route configuration is declared, it may contain route guard arguments. All route +guards associated with a route declaration must be `true` for the route configuration to +be used for a given request during a check. If any guard in the set of route guard arguments provided to a route configuration returns `false` during a check, that route is skipped and route matching continues through the ordered set of routes. If any route matches, the route matching process stops and the handler associated with -the route is invoked. If no route matches after all route patterns are exhausted, a *NOT FOUND* response get returned. +the route is invoked. If no route matches after all route patterns are exhausted, a +*NOT FOUND* response get returned. # Resource pattern syntax @@ -278,10 +277,6 @@ All values representing matched path segments are available in Specific values can be retrieved with [`Params::get()`](../actix_web/dev/struct.Params.html#method.get). -Any matched parameter can be deserialized into a specific type if the type -implements the `FromParam` trait. For example most standard integer types -the trait, i.e.: - {{< include-example example="url-dispatch" file="minfo.rs" section="minfo" >}} For this example for path '/a/1/2/', values v1 and v2 will resolve to "1" and "2". @@ -304,9 +299,6 @@ safe to interpolate within, or use as a suffix of, a path without additional che {{< include-example example="url-dispatch" file="pbuf.rs" section="pbuf" >}} -List of `FromParam` implementations can be found in -[api docs](../../actix-web/actix_web/dev/trait.FromParam.html#foreign-impls) - ## Path information extractor Actix provides functionality for type safe path information extraction. @@ -383,8 +375,8 @@ It is possible to register path normalization only for *GET* requests only: ## Using an Application Prefix to Compose Applications -The `App::prefix()` method allows to set a specific application prefix. -This prefix represents a resource prefix that will be prepended to all resource patterns added +The `web::scope()` method allows to set a specific application scope. +This scope represents a resource prefix that will be prepended to all resource patterns added by the resource configuration. This can be used to help mount a set of routes at a different location than the included callable's author intended while still maintaining the same resource names. @@ -394,30 +386,30 @@ For example: {{< include-example example="url-dispatch" file="scope.rs" section="scope" >}} In the above example, the *show_users* route will have an effective route pattern of -*/users/show* instead of */show* because the application's prefix argument will be prepended +*/users/show* instead of */show* because the application's scope will be prepended to the pattern. The route will then only match if the URL path is */users/show*, and when the `HttpRequest.url_for()` function is called with the route name show_users, it will generate a URL with that same path. -# Custom route predicates +# Custom route guard -You can think of a predicate as a simple function that accepts a *request* object reference -and returns *true* or *false*. Formally, a predicate is any object that implements the -[`Predicate`](../actix_web/pred/trait.Predicate.html) trait. Actix provides +You can think of a guard as a simple function that accepts a *request* object reference +and returns *true* or *false*. Formally, a guard is any object that implements the +[`Guard`](../actix_web/guard/trait.Guard.html) trait. Actix provides several predicates, you can check -[functions section](../../actix-web/actix_web/pred/index.html#functions) of api docs. +[functions section](../../actix-web/actix_web/guard/index.html#functions) of api docs. -Here is a simple predicate that check that a request contains a specific *header*: +Here is a simple guard that check that a request contains a specific *header*: {{< include-example example="url-dispatch" file="pred.rs" section="pred" >}} In this example, *index* handler will be called only if request contains *CONTENT-TYPE* header. -Predicates have access to the application's state via `HttpRequest::state()`. +Guards have access to the application's state via `HttpRequest::data()`. Also predicates can store extra information in [request extensions](../../actix-web/actix_web/struct.HttpRequest.html#method.extensions). -## Modifying predicate values +## Modifying guard values You can invert the meaning of any predicate value by wrapping it in a `Not` predicate. For example, if you want to return "METHOD NOT ALLOWED" response for all methods @@ -425,26 +417,26 @@ except "GET": {{< include-example example="url-dispatch" file="pred2.rs" section="pred" >}} -The `Any` predicate accepts a list of predicates and matches if any of the supplied -predicates match. i.e: +The `Any` guard accepts a list of guards and matches if any of the supplied +guards match. i.e: ```rust -pred::Any(pred::Get()).or(pred::Post()) +guard::Any(guard::Get()).or(guard::Post()) ``` -The `All` predicate accepts a list of predicates and matches if all of the supplied -predicates match. i.e: +The `All` guard accepts a list of guard and matches if all of the supplied +guards match. i.e: ```rust -pred::All(pred::Get()).and(pred::Header("content-type", "plain/text")) +guard::All(guard::Get()).and(guard::Header("content-type", "plain/text")) ``` # Changing the default Not Found response If the path pattern can not be found in the routing table or a resource can not find matching route, the default resource is used. The default response is *NOT FOUND*. -It is possible to override the *NOT FOUND* response with `App::default_resource()`. +It is possible to override the *NOT FOUND* response with `App::default_service()`. This method accepts a *configuration function* same as normal resource configuration -with `App::resource()` method. +with `App::service()` method. {{< include-example example="url-dispatch" file="dhandler.rs" section="default" >}} diff --git a/examples/url-dispatch/src/cfg.rs b/examples/url-dispatch/src/cfg.rs index 23c9490..de4de25 100644 --- a/examples/url-dispatch/src/cfg.rs +++ b/examples/url-dispatch/src/cfg.rs @@ -3,7 +3,7 @@ use actix_web::{guard, web, App, HttpResponse}; pub fn main() { App::new().service( - web::resource("/").route( + web::resource("/path").route( web::route() .guard(guard::Get()) .guard(guard::Header("content-type", "text/plain")) diff --git a/examples/url-dispatch/src/main.rs b/examples/url-dispatch/src/main.rs index b1c30a2..c2e4ae0 100644 --- a/examples/url-dispatch/src/main.rs +++ b/examples/url-dispatch/src/main.rs @@ -23,6 +23,6 @@ fn index(_req: HttpRequest) -> HttpResponse { fn main() { App::new() .route("/user/{name}", web::get().to(index)) - .route("/user/{name}", web::get().to(index)); + .route("/user/{name}", web::post().to(index)); } // diff --git a/examples/url-dispatch/src/minfo.rs b/examples/url-dispatch/src/minfo.rs index f26ac0a..3ce4a6c 100644 --- a/examples/url-dispatch/src/minfo.rs +++ b/examples/url-dispatch/src/minfo.rs @@ -1,13 +1,16 @@ // -use actix_web::{web, App, HttpRequest, Result}; +use actix_web::{web, App, HttpRequest, HttpServer, Result}; fn index(req: HttpRequest) -> Result { - let v1: u8 = req.match_info().query("v1").parse().unwrap(); + let v1: u8 = req.match_info().get("v1").unwrap().parse().unwrap(); let v2: u8 = req.match_info().query("v2").parse().unwrap(); - Ok(format!("Values {} {}", v1, v2)) + let (v3, v4): (u8, u8) = req.match_info().load().unwrap(); + Ok(format!("Values {} {} {} {}", v1, v2, v3, v4)) } fn main() { - App::new().route(r"/a/{v1}/{v2}/", web::get().to(index)); + App::new() + .route("/a/{v1}/{v2}/", web::get().to(index)) + .route("", web::get().to(|| actix_web::HttpResponse::Ok())); } // diff --git a/examples/url-dispatch/src/path2.rs b/examples/url-dispatch/src/path2.rs index 2524342..53d4532 100644 --- a/examples/url-dispatch/src/path2.rs +++ b/examples/url-dispatch/src/path2.rs @@ -12,7 +12,7 @@ fn index(info: web::Path) -> Result { Ok(format!("Welcome {}!", info.username)) } -fn main() { +pub fn main() { App::new().route( "/{username}/index.html", // <- define path parameters web::get().to(index), diff --git a/examples/url-dispatch/src/resource.rs b/examples/url-dispatch/src/resource.rs index 1dd5639..f2d98db 100644 --- a/examples/url-dispatch/src/resource.rs +++ b/examples/url-dispatch/src/resource.rs @@ -7,7 +7,7 @@ fn index(_req: HttpRequest) -> HttpResponse { fn main() { App::new() - .service(web::resource("/prefix").route(web::get().to(index))) + .service(web::resource("/prefix").to(index)) .service( web::resource("/user/{name}").route(web::get().to(|| HttpResponse::Ok())), ); diff --git a/examples/url-dispatch/src/url_ext.rs b/examples/url-dispatch/src/url_ext.rs index 6327192..eaa2503 100644 --- a/examples/url-dispatch/src/url_ext.rs +++ b/examples/url-dispatch/src/url_ext.rs @@ -1,15 +1,17 @@ // -use actix_web::{web, App, Error, HttpRequest, HttpResponse}; +use actix_web::{web, App, Error, HttpRequest, HttpResponse, Responder}; -fn index(req: HttpRequest) -> Result { - let url = req.url_for("youtube", &["oHg5SJYRHA0"])?; +fn index(req: HttpRequest) -> impl Responder { + let url = req.url_for("youtube", &["oHg5SJYRHA0"]).unwrap(); assert_eq!(url.as_str(), "https://youtube.com/watch/oHg5SJYRHA0"); - Ok(HttpResponse::Ok().into()) + + url.into_string() } -fn main() { +pub fn main() { App::new() - .service(web::resource("/index.html").route(web::get().to(index))) - .external_resource("youtube", "https://youtube.com/watch/{video_id}"); + .route("/index.html", web::get().to(index)) + .external_resource("youtube", "https://youtube.com/watch/{video_id}") + .route("/", actix_web::web::get().to(index)); } // diff --git a/examples/url-dispatch/src/urls.rs b/examples/url-dispatch/src/urls.rs index 814cc9f..e1ab4dc 100644 --- a/examples/url-dispatch/src/urls.rs +++ b/examples/url-dispatch/src/urls.rs @@ -10,7 +10,7 @@ fn index(req: HttpRequest) -> Result { .finish()) } -fn main() { +pub fn main() { App::new() .service( web::resource("/test/{a}/{b}/{c}")