1
0
mirror of https://github.com/actix/actix-website synced 2024-11-27 18:12:57 +01:00

First pass at 'Application' section

This commit is contained in:
Cameron Dershem 2019-06-13 03:24:25 -04:00
parent 577dd90341
commit 992d182910
11 changed files with 91 additions and 146 deletions

View File

@ -78,35 +78,33 @@ This limitation can easily be overcome with the [App::boxed](https://docs.rs/act
{{< include-example example="application" file="state.rs" section="combine" >}} {{< include-example example="application" file="state.rs" section="combine" >}}
## Using an Application Prefix to Compose Applications ## Using an Application Scope to Compose Applications
The `App::prefix()` method allows to set a specific application prefix. The `web::wcope()` method allows to set a specific application prefix.
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.
For example: For example:
{{< include-example example="url-dispatch" file="prefix.rs" section="prefix" >}} {{< 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 argument 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.
## Application predicates and virtual hosting ## Application guards and virtual hosting
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 guards, 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.
Any of this predicates could be used One of the provided guards is [`Host`](../actix_web/guard/fn.Host.html), it can be used
with [`App::filter()`](../actix_web/struct.App.html#method.filter) method. One of the
provided predicates is [`Host`](../actix_web/pred/fn.Host.html), it can be used
as application's filter based on request's host information. as application's filter based on request's host information.
{{< include-example example="application" file="vh.rs" section="vh" >}} {{< include-example example="application" file="vh.rs" section="vh" >}}

View File

@ -27,7 +27,6 @@ actix-web = "{{< actix-version "actix-web" >}}"
In order to implement a web server, we first need to create a request handler. In order to implement a web server, we first need to create a request handler.
<!-- TODO: Handler has been deprecated -->
A request handler is a function that accepts an `HttpRequest` instance as its only parameter A request handler is a function that accepts an `HttpRequest` instance as its only parameter
and returns a type that can be converted into `HttpResponse`: and returns a type that can be converted into `HttpResponse`:

View File

@ -391,7 +391,7 @@ resource names.
For example: For example:
{{< include-example example="url-dispatch" file="prefix.rs" section="prefix" >}} {{< 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 prefix argument will be prepended

View File

@ -1,6 +1,7 @@
[package] [package]
name = "application" name = "application"
version = "0.7.0" version = "0.7.0"
edition = "2018"
workspace = "../" workspace = "../"
[dependencies] [dependencies]

View File

@ -1,36 +1,31 @@
#![allow(unused)] #![allow(unused_variables)]
extern crate actix_web; use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer, Responder};
use actix_web::{http::Method, server, App, HttpRequest, HttpResponse, Responder};
mod state; mod state;
mod vh; mod vh;
#[rustfmt::skip]
fn make_app() { fn make_app() {
// <make_app> // <make_app>
fn index(req: &HttpRequest) -> impl Responder { fn index(_req: HttpRequest) -> impl Responder {
"Hello world!" "Hello world!"
} }
let app = App::new() let app = App::new()
.prefix("/app") .service(web::scope("/app").route("/index.html", web::get().to(index)));
.resource("/index.html", |r| r.method(Method::GET).f(index))
.finish()
// </make_app> // </make_app>
;
} }
#[rustfmt::skip]
fn run_server() { fn run_server() {
// <run_server> // <run_server>
let server = server::new(|| { let server = HttpServer::new(|| {
vec![
App::new() App::new()
.prefix("/app1") .service(web::scope("/app1").route("/", web::to(|| HttpResponse::Ok())))
.resource("/", |r| r.f(|r| HttpResponse::Ok())), .service(web::scope("/app2").route("/", web::to(|| HttpResponse::Ok())))
App::new() .route("/", web::to(|| HttpResponse::Ok()))
.prefix("/app2")
.resource("/", |r| r.f(|r| HttpResponse::Ok())),
App::new().resource("/", |r| r.f(|r| HttpResponse::Ok())),
]
}); });
// </run_server> // </run_server>
} }

View File

@ -1,5 +1,6 @@
#![allow(dead_code, unused)]
// <setup> // <setup>
use actix_web::{http, App, HttpRequest}; use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer};
use std::cell::Cell; use std::cell::Cell;
// This struct represents state // This struct represents state
@ -7,38 +8,41 @@ struct AppState {
counter: Cell<usize>, counter: Cell<usize>,
} }
fn index(req: &HttpRequest<AppState>) -> String { fn index(data: web::Data<AppState>) -> String {
let count = req.state().counter.get() + 1; // <- get count let count = data.counter.get() + 1; // <- get count
req.state().counter.set(count); // <- store new count in state data.counter.set(count); // <- store new count in state
format!("Request number: {}", count) // <- response with count format!("Request number: {}", count) // <- response with count
} }
// </setup> // </setup>
#[rustfmt::skip]
fn make_app() { fn make_app() {
// <make_app> // <make_app>
App::with_state(AppState { counter: Cell::new(0) }) App::new()
.resource("/", |r| r.method(http::Method::GET).f(index)) .data( AppState { counter: Cell::new(0) })
.finish() .route("/", web::get().to(index));
// </make_app> // </make_app>
;
} }
#[rustfmt::skip]
fn start_app() { fn start_app() {
// <start_app> // <start_app>
server::new(|| { HttpServer::new(|| {
App::with_state(AppState { counter: Cell::new(0) }) App::new()
.resource("/", |r| r.method(http::Method::GET).f(index)) .data( AppState { counter: Cell::new(0) })
}).bind("127.0.0.1:8080") .route("/", web::get().to(index))
})
.bind("127.0.0.1:8088")
.unwrap() .unwrap()
.run() .run()
.unwrap();
// </start_app> // </start_app>
;
} }
use actix_web::{server, HttpResponse};
use std::thread; use std::thread;
#[rustfmt::skip]
fn combine() { fn combine() {
thread::spawn(|| { thread::spawn(|| {
// <combine> // <combine>
@ -46,20 +50,23 @@ struct State1;
struct State2; struct State2;
fn main() { fn main() {
server::new(|| { HttpServer::new(|| {
vec![ App::new()
App::with_state(State1) .data(State1)
.prefix("/app1") .data(State2)
.resource("/", |r| r.f(|r| HttpResponse::Ok())) .service(
.boxed(), web::scope("/app1")
App::with_state(State2) .route("/", web::to(|| HttpResponse::Ok())),
.prefix("/app2") )
.resource("/", |r| r.f(|r| HttpResponse::Ok())) .service(
.boxed(), web::scope("/app2")
] .route("/", web::to(|| HttpResponse::Ok())),
}).bind("127.0.0.1:8080") )
})
.bind("127.0.0.1:8088")
.unwrap() .unwrap()
.run() .run()
.unwrap();
} }
// </combine> // </combine>
}); });

View File

@ -1,20 +1,22 @@
#![allow(unused)] #![allow(unused)]
use actix_web::{http::Method, pred, server, App, HttpRequest, HttpResponse, Responder}; use actix_web::{guard, web, App, HttpRequest, HttpResponse, HttpServer, Responder};
// <vh> // <vh>
fn main() { fn main() {
let server = server::new(|| { HttpServer::new(|| {
vec![
App::new() App::new()
.filter(pred::Host("www.rust-lang.org")) .service(
.resource("/", |r| r.f(|r| HttpResponse::Ok())), web::scope("/")
App::new() .guard(guard::Header("Host", "www.rust-lang.org"))
.filter(pred::Host("users.rust-lang.org")) .route("", web::to(|| HttpResponse::Ok())),
.resource("/", |r| r.f(|r| HttpResponse::Ok())), )
App::new().resource("/", |r| r.f(|r| HttpResponse::Ok())), .service(
] web::scope("/")
}); .guard(guard::Header("Host", "users.rust-lang.org"))
.route("", web::to(|| HttpResponse::Ok())),
server.run(); )
.route("/", web::to(|| HttpResponse::Ok()))
})
.run();
} }
// </vh> // </vh>

View File

@ -9,4 +9,3 @@ actix-web = "1.0"
futures = "0.1" futures = "0.1"
openssl = "0.10" openssl = "0.10"
serde = "1.0" serde = "1.0"
serde_derive = "1.0"

View File

@ -3,7 +3,6 @@ extern crate actix_web;
extern crate futures; extern crate futures;
extern crate openssl; extern crate openssl;
#[macro_use] #[macro_use]
extern crate serde_derive;
extern crate serde; extern crate serde;
mod cfg; mod cfg;
@ -16,9 +15,9 @@ mod path2;
mod pbuf; mod pbuf;
mod pred; mod pred;
mod pred2; mod pred2;
mod prefix;
mod resource; mod resource;
mod scope; mod scope;
mod scope;
mod url_ext; mod url_ext;
mod urls; mod urls;

View File

@ -1,14 +0,0 @@
use actix_web::{App, HttpRequest, HttpResponse};
// <prefix>
fn show_users(req: &HttpRequest) -> HttpResponse {
unimplemented!()
}
fn main() {
App::new()
.prefix("/users")
.resource("/show", |r| r.f(show_users))
.finish();
}
// </prefix>

View File

@ -1,54 +1,13 @@
#![allow(dead_code)] use actix_web::{App, HttpRequest, HttpResponse};
use actix_web::{http::Method, App, HttpRequest};
fn get_projects(_: &HttpRequest) -> String {
unimplemented!()
}
fn create_project(_: &HttpRequest) -> String {
unimplemented!()
}
fn update_project(_: HttpRequest) -> String {
unimplemented!()
}
fn delete_project(_: &HttpRequest) -> String {
unimplemented!()
}
fn get_tasks(_: &HttpRequest) -> String {
unimplemented!()
}
fn create_task(_: &HttpRequest) -> String {
unimplemented!()
}
fn update_task(_: HttpRequest) -> String {
unimplemented!()
}
fn delete_task(_: HttpRequest) -> String {
unimplemented!()
}
fn main() {
// <scope> // <scope>
App::new().scope("/project", |proj_scope| { fn show_users(_req: HttpRequest) -> HttpResponse {
proj_scope unimplemented!()
.resource("", |r| {
r.method(Method::GET).f(get_projects);
r.method(Method::POST).f(create_project)
})
.resource("/{project_id}", |r| {
r.method(Method::PUT).with(update_project);
r.method(Method::DELETE).f(delete_project)
})
.nested("/{project_id}/task", |task_scope| {
task_scope
.resource("", |r| {
r.method(Method::GET).f(get_tasks);
r.method(Method::POST).f(create_task)
})
.resource("/{task_id}", |r| {
r.method(Method::PUT).with(update_task);
r.method(Method::DELETE).with(delete_task)
})
})
});
// </scope>
} }
#[rustfmt::skip]
fn main() {
App::new().service(
web::scope("/users") .route("/show", web::to(show_users)))
}
// </scope>