mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-24 16:02:59 +01:00
App::route method
This commit is contained in:
parent
7becb95a97
commit
fffaf2bb2d
@ -17,18 +17,42 @@ A resource also has a pattern, meant to match against the *PATH* portion of a *U
|
||||
It does not match against the *QUERY* portion (the portion following the scheme and
|
||||
port, e.g., */foo/bar* in the *URL* *http://localhost:8080/foo/bar?q=value*).
|
||||
|
||||
The [App::resource](../actix_web/struct.App.html#method.resource) methods
|
||||
add a single resource to application routing table. This method accepts a *path pattern*
|
||||
The [App::route](../actix_web/struct.App.html#method.route) method provides
|
||||
simple way of registering routes. This method adds a single route to application
|
||||
routing table. This method accepts a *path pattern*,
|
||||
*http method* and a handler function. `route()` method could be called multiple times
|
||||
for the same path, in that case, multiple routes register for the same resource path.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
use actix_web::{App, HttpRequest, HttpResponse, http::Method};
|
||||
|
||||
fn index(req: HttpRequest) -> HttpResponse {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.route("/user/{name}", Method::GET, index)
|
||||
.route("/user/{name}", Method::POST, index)
|
||||
.finish();
|
||||
}
|
||||
```
|
||||
|
||||
While *App::route()* provides simple way of registering routes, to access
|
||||
complete resource configuration, different method has to be used.
|
||||
The [App::resource](../actix_web/struct.App.html#method.resource) method
|
||||
adds a single resource to application routing table. This method accepts a *path pattern*
|
||||
and a resource configuration function.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
# use actix_web::{App, HttpRequest, HttpResponse, http::Method};
|
||||
#
|
||||
# fn index(req: HttpRequest) -> HttpResponse {
|
||||
# unimplemented!()
|
||||
# }
|
||||
#
|
||||
use actix_web::{App, HttpRequest, HttpResponse, http::Method};
|
||||
|
||||
fn index(req: HttpRequest) -> HttpResponse {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.resource("/prefix", |r| r.f(index))
|
||||
|
@ -3,11 +3,12 @@ use std::rc::Rc;
|
||||
use std::cell::UnsafeCell;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use http::Method;
|
||||
use handler::Reply;
|
||||
use router::{Router, Resource};
|
||||
use resource::{ResourceHandler};
|
||||
use header::ContentEncoding;
|
||||
use handler::{Handler, RouteHandler, WrapHandler};
|
||||
use handler::{Handler, RouteHandler, WrapHandler, FromRequest, Responder};
|
||||
use httprequest::HttpRequest;
|
||||
use pipeline::{Pipeline, PipelineHandler, HandlerType};
|
||||
use middleware::Middleware;
|
||||
@ -225,6 +226,52 @@ impl<S> App<S> where S: 'static {
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure route for specific path.
|
||||
///
|
||||
/// This is simplified version of `App::resource()` method.
|
||||
/// Handler function needs to accept one request extractor argument.
|
||||
/// This method could be called multiple times, in that case multiple routes
|
||||
/// would be registered for same resource path.
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate actix_web;
|
||||
/// use actix_web::{http, App, HttpRequest, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .route("/test", http::Method::GET,
|
||||
/// |_: HttpRequest| HttpResponse::Ok())
|
||||
/// .route("/test", http::Method::POST,
|
||||
/// |_: HttpRequest| HttpResponse::MethodNotAllowed());
|
||||
/// }
|
||||
/// ```
|
||||
pub fn route<T, F, R>(mut self, path: &str, method: Method, f: F) -> App<S>
|
||||
where F: Fn(T) -> R + 'static,
|
||||
R: Responder + 'static,
|
||||
T: FromRequest<S> + 'static,
|
||||
{
|
||||
{
|
||||
let parts: &mut ApplicationParts<S> = unsafe{
|
||||
mem::transmute(self.parts.as_mut().expect("Use after finish"))};
|
||||
|
||||
// get resource handler
|
||||
for (pattern, handler) in &mut parts.resources {
|
||||
if let Some(ref mut handler) = handler {
|
||||
if pattern.pattern() == path {
|
||||
handler.method(method).with(f);
|
||||
return self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut handler = ResourceHandler::default();
|
||||
handler.method(method).with(f);
|
||||
let pattern = Resource::new(handler.get_name(), path);
|
||||
parts.resources.push((pattern, Some(handler)));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure resource for specific path.
|
||||
///
|
||||
/// Resource may have variable path also. For instance, a resource with
|
||||
@ -261,12 +308,12 @@ impl<S> App<S> where S: 'static {
|
||||
{
|
||||
let parts = self.parts.as_mut().expect("Use after finish");
|
||||
|
||||
// add resource
|
||||
let mut resource = ResourceHandler::default();
|
||||
f(&mut resource);
|
||||
// add resource handler
|
||||
let mut handler = ResourceHandler::default();
|
||||
f(&mut handler);
|
||||
|
||||
let pattern = Resource::new(resource.get_name(), path);
|
||||
parts.resources.push((pattern, Some(resource)));
|
||||
let pattern = Resource::new(handler.get_name(), path);
|
||||
parts.resources.push((pattern, Some(handler)));
|
||||
}
|
||||
self
|
||||
}
|
||||
@ -603,6 +650,26 @@ mod tests {
|
||||
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_route() {
|
||||
let mut app = App::new()
|
||||
.route("/test", Method::GET, |_: HttpRequest| HttpResponse::Ok())
|
||||
.route("/test", Method::POST, |_: HttpRequest| HttpResponse::Created())
|
||||
.finish();
|
||||
|
||||
let req = TestRequest::with_uri("/test").method(Method::GET).finish();
|
||||
let resp = app.run(req);
|
||||
assert_eq!(resp.as_response().unwrap().status(), StatusCode::OK);
|
||||
|
||||
let req = TestRequest::with_uri("/test").method(Method::POST).finish();
|
||||
let resp = app.run(req);
|
||||
assert_eq!(resp.as_response().unwrap().status(), StatusCode::CREATED);
|
||||
|
||||
let req = TestRequest::with_uri("/test").method(Method::HEAD).finish();
|
||||
let resp = app.run(req);
|
||||
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_handler_prefix() {
|
||||
let mut app = App::new()
|
||||
|
@ -102,7 +102,7 @@ impl<S: 'static> Route<S> {
|
||||
self.handler = InnerHandler::async(handler);
|
||||
}
|
||||
|
||||
/// Set handler function with http request extractor.
|
||||
/// Set handler function, use request extractor for paramters.
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate bytes;
|
||||
@ -137,7 +137,7 @@ impl<S: 'static> Route<S> {
|
||||
cfg
|
||||
}
|
||||
|
||||
/// Set handler function, function has to accept two request extractors.
|
||||
/// Set handler function, use request extractor for both paramters.
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate bytes;
|
||||
@ -180,7 +180,7 @@ impl<S: 'static> Route<S> {
|
||||
(cfg1, cfg2)
|
||||
}
|
||||
|
||||
/// Set handler function, function has to accept three request extractors.
|
||||
/// Set handler function, use request extractor for all paramters.
|
||||
pub fn with3<T1, T2, T3, F, R>(&mut self, handler: F)
|
||||
-> (ExtractorConfig<S, T1>, ExtractorConfig<S, T2>, ExtractorConfig<S, T3>)
|
||||
where F: Fn(T1, T2, T3) -> R + 'static,
|
||||
|
Loading…
Reference in New Issue
Block a user