mirror of
https://github.com/actix/actix-website
synced 2025-01-22 16:15:56 +01:00
First pass at url-dispatch chapter.
This commit is contained in:
parent
35156b0a75
commit
71e6f076a4
@ -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<S>) -> 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<S>) -> 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<S>) -> Future<Item = HttpResponse, Error = Error> + 'static`
|
||||
`Fn(HttpRequest<S>) -> Future<Item = HttpResponse, Error = Error> + '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" >}}
|
||||
|
@ -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"))
|
||||
|
@ -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));
|
||||
}
|
||||
// </main>
|
||||
|
@ -1,13 +1,16 @@
|
||||
// <minfo>
|
||||
use actix_web::{web, App, HttpRequest, Result};
|
||||
use actix_web::{web, App, HttpRequest, HttpServer, Result};
|
||||
|
||||
fn index(req: HttpRequest) -> Result<String> {
|
||||
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()));
|
||||
}
|
||||
// </minfo>
|
||||
|
@ -12,7 +12,7 @@ fn index(info: web::Path<Info>) -> Result<String> {
|
||||
Ok(format!("Welcome {}!", info.username))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
pub fn main() {
|
||||
App::new().route(
|
||||
"/{username}/index.html", // <- define path parameters
|
||||
web::get().to(index),
|
||||
|
@ -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())),
|
||||
);
|
||||
|
@ -1,15 +1,17 @@
|
||||
// <ext>
|
||||
use actix_web::{web, App, Error, HttpRequest, HttpResponse};
|
||||
use actix_web::{web, App, Error, HttpRequest, HttpResponse, Responder};
|
||||
|
||||
fn index(req: HttpRequest) -> Result<HttpResponse, Error> {
|
||||
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));
|
||||
}
|
||||
// </ext>
|
||||
|
@ -10,7 +10,7 @@ fn index(req: HttpRequest) -> Result<HttpResponse> {
|
||||
.finish())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
pub fn main() {
|
||||
App::new()
|
||||
.service(
|
||||
web::resource("/test/{a}/{b}/{c}")
|
||||
|
Loading…
x
Reference in New Issue
Block a user