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
|
||||||
|
|
||||||
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,
|
matching language. If one of the patterns matches the path information associated with a request,
|
||||||
a particular handler object is invoked.
|
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
|
[*Route*](../../actix-web/actix_web/dev/struct.Route.html) object. Route can be configured with a
|
||||||
builder-like pattern. Following configuration methods are available:
|
builder-like pattern. Following configuration methods are available:
|
||||||
|
|
||||||
* [*Route::filter()*](../../actix-web/actix_web/dev/struct.Route.html#method.filter)
|
* [*Route::guard()*](../../actix-web/actix_web/dev/struct.Route.html#method.guard)
|
||||||
registers a new predicate. Any number of predicates can be registered for each route.
|
registers a new guard. Any number of guards can be registered for each route.
|
||||||
* [*Route::f()*](../../actix-web/actix_web/dev/struct.Route.html#method.f) registers
|
* [*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.
|
handler function for this route. Only one handler can be registered.
|
||||||
Usually handler registration
|
Usually handler registration
|
||||||
is the last config operation. Handler function can be a function or closure
|
is the last config operation. Handler function can be a function or closure
|
||||||
and has the type
|
and has the type
|
||||||
`Fn(&HttpRequest<S>) -> R + 'static`
|
`Fn(HttpRequest<S>) -> R + 'static`
|
||||||
* [*Route::h()*](../../actix-web/actix_web/dev/struct.Route.html#method.h) registers
|
* [*Route::to_async()*](../../actix-web/actix_web/dev/struct.Route.html#method.to_async) 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
|
|
||||||
an async handler function for this route. Only one handler can be registered.
|
an async handler function for this route. Only one handler can be registered.
|
||||||
Handler registration is the last config operation. Handler function can
|
Handler registration is the last config operation. Handler function can
|
||||||
be a function or closure and has the type
|
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
|
# 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 routes were declared via `App::resource()` method. If resource can not be found,
|
||||||
the *default resource* is used as the matched resource.
|
the *default resource* is used as the matched resource.
|
||||||
|
|
||||||
When a route configuration is declared, it may contain route predicate arguments. All route
|
When a route configuration is declared, it may contain route guard arguments. All route
|
||||||
predicates associated with a route declaration must be `true` for the route configuration to
|
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 predicate in the set of route predicate
|
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
|
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.
|
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
|
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
|
# Resource pattern syntax
|
||||||
|
|
||||||
@ -278,10 +277,6 @@ All values representing matched path segments are available in
|
|||||||
Specific values can be retrieved with
|
Specific values can be retrieved with
|
||||||
[`Params::get()`](../actix_web/dev/struct.Params.html#method.get).
|
[`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" >}}
|
{{< 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".
|
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" >}}
|
{{< 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
|
## Path information extractor
|
||||||
|
|
||||||
Actix provides functionality for type safe path information extraction.
|
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
|
## Using an Application Prefix to Compose Applications
|
||||||
|
|
||||||
The `App::prefix()` method allows to set a specific application prefix.
|
The `web::scope()` method allows to set a specific application scope.
|
||||||
This prefix represents a resource prefix that will be prepended to all resource patterns added
|
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
|
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
|
location than the included callable's author intended while still maintaining the same
|
||||||
resource names.
|
resource names.
|
||||||
@ -394,30 +386,30 @@ For example:
|
|||||||
{{< include-example example="url-dispatch" file="scope.rs" section="scope" >}}
|
{{< 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
|
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*,
|
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,
|
and when the `HttpRequest.url_for()` function is called with the route name show_users,
|
||||||
it will generate a URL with that same path.
|
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
|
You can think of a guard as a simple function that accepts a *request* object reference
|
||||||
and returns *true* or *false*. Formally, a predicate is any object that implements the
|
and returns *true* or *false*. Formally, a guard is any object that implements the
|
||||||
[`Predicate`](../actix_web/pred/trait.Predicate.html) trait. Actix provides
|
[`Guard`](../actix_web/guard/trait.Guard.html) trait. Actix provides
|
||||||
several predicates, you can check
|
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" >}}
|
{{< 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.
|
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
|
Also predicates can store extra information in
|
||||||
[request extensions](../../actix-web/actix_web/struct.HttpRequest.html#method.extensions).
|
[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.
|
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
|
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" >}}
|
{{< 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
|
The `Any` guard accepts a list of guards and matches if any of the supplied
|
||||||
predicates match. i.e:
|
guards match. i.e:
|
||||||
|
|
||||||
```rust
|
```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
|
The `All` guard accepts a list of guard and matches if all of the supplied
|
||||||
predicates match. i.e:
|
guards match. i.e:
|
||||||
|
|
||||||
```rust
|
```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
|
# 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
|
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*.
|
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
|
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" >}}
|
{{< include-example example="url-dispatch" file="dhandler.rs" section="default" >}}
|
||||||
|
@ -3,7 +3,7 @@ use actix_web::{guard, web, App, HttpResponse};
|
|||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
App::new().service(
|
App::new().service(
|
||||||
web::resource("/").route(
|
web::resource("/path").route(
|
||||||
web::route()
|
web::route()
|
||||||
.guard(guard::Get())
|
.guard(guard::Get())
|
||||||
.guard(guard::Header("content-type", "text/plain"))
|
.guard(guard::Header("content-type", "text/plain"))
|
||||||
|
@ -23,6 +23,6 @@ fn index(_req: HttpRequest) -> HttpResponse {
|
|||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.route("/user/{name}", web::get().to(index))
|
.route("/user/{name}", web::get().to(index))
|
||||||
.route("/user/{name}", web::get().to(index));
|
.route("/user/{name}", web::post().to(index));
|
||||||
}
|
}
|
||||||
// </main>
|
// </main>
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
// <minfo>
|
// <minfo>
|
||||||
use actix_web::{web, App, HttpRequest, Result};
|
use actix_web::{web, App, HttpRequest, HttpServer, Result};
|
||||||
|
|
||||||
fn index(req: HttpRequest) -> Result<String> {
|
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();
|
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() {
|
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>
|
// </minfo>
|
||||||
|
@ -12,7 +12,7 @@ fn index(info: web::Path<Info>) -> Result<String> {
|
|||||||
Ok(format!("Welcome {}!", info.username))
|
Ok(format!("Welcome {}!", info.username))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
pub fn main() {
|
||||||
App::new().route(
|
App::new().route(
|
||||||
"/{username}/index.html", // <- define path parameters
|
"/{username}/index.html", // <- define path parameters
|
||||||
web::get().to(index),
|
web::get().to(index),
|
||||||
|
@ -7,7 +7,7 @@ fn index(_req: HttpRequest) -> HttpResponse {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.service(web::resource("/prefix").route(web::get().to(index)))
|
.service(web::resource("/prefix").to(index))
|
||||||
.service(
|
.service(
|
||||||
web::resource("/user/{name}").route(web::get().to(|| HttpResponse::Ok())),
|
web::resource("/user/{name}").route(web::get().to(|| HttpResponse::Ok())),
|
||||||
);
|
);
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
// <ext>
|
// <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> {
|
fn index(req: HttpRequest) -> impl Responder {
|
||||||
let url = req.url_for("youtube", &["oHg5SJYRHA0"])?;
|
let url = req.url_for("youtube", &["oHg5SJYRHA0"]).unwrap();
|
||||||
assert_eq!(url.as_str(), "https://youtube.com/watch/oHg5SJYRHA0");
|
assert_eq!(url.as_str(), "https://youtube.com/watch/oHg5SJYRHA0");
|
||||||
Ok(HttpResponse::Ok().into())
|
|
||||||
|
url.into_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
pub fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.service(web::resource("/index.html").route(web::get().to(index)))
|
.route("/index.html", web::get().to(index))
|
||||||
.external_resource("youtube", "https://youtube.com/watch/{video_id}");
|
.external_resource("youtube", "https://youtube.com/watch/{video_id}")
|
||||||
|
.route("/", actix_web::web::get().to(index));
|
||||||
}
|
}
|
||||||
// </ext>
|
// </ext>
|
||||||
|
@ -10,7 +10,7 @@ fn index(req: HttpRequest) -> Result<HttpResponse> {
|
|||||||
.finish())
|
.finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
pub fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.service(
|
.service(
|
||||||
web::resource("/test/{a}/{b}/{c}")
|
web::resource("/test/{a}/{b}/{c}")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user