1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-02-22 20:13:17 +01:00
actix-web/guide/src/qs_3.md

110 lines
4.0 KiB
Markdown
Raw Normal View History

2017-12-01 23:06:15 -08:00
# Application
2017-11-28 12:44:59 -08:00
Actix web provides some primitives to build web servers and applications with Rust.
It provides routing, middlewares, pre-processing of requests, and post-processing of responses,
2018-01-13 11:17:48 -08:00
websocket protocol handling, multipart streams, etc.
2017-11-28 12:44:59 -08:00
2018-03-28 22:16:01 +02:00
All actix web servers are built around the `Application` instance.
It is used for registering routes for resources, and middlewares.
It also stores application specific state that is shared across all handlers
2017-11-28 12:44:59 -08:00
within same application.
2018-03-28 22:16:01 +02:00
Application acts as a namespace for all routes, i.e all routes for a specific application
have the same url path prefix. The application prefix always contains a leading "/" slash.
If supplied prefix does not contain leading slash, it gets inserted.
The prefix should consist of value path segments. i.e for an application with prefix `/app`
any request with the paths `/app`, `/app/` or `/app/test` would match,
but path `/application` would not match.
2017-11-28 12:44:59 -08:00
```rust,ignore
2017-12-04 13:32:05 -08:00
# extern crate actix_web;
# extern crate tokio_core;
# use actix_web::*;
# fn index(req: HttpRequest) -> &'static str {
# "Hello world!"
# }
# fn main() {
let app = Application::new()
.prefix("/app")
.resource("/index.html", |r| r.method(Method::GET).f(index))
2017-11-28 12:44:59 -08:00
.finish()
2017-12-04 13:32:05 -08:00
# }
2017-11-28 12:44:59 -08:00
```
In this example application with `/app` prefix and `index.html` resource
2018-03-28 22:16:01 +02:00
gets created. This resource is available as on `/app/index.html` url.
For more information check
[*URL Matching*](./qs_5.html#using-a-application-prefix-to-compose-applications) section.
2017-12-01 23:32:15 -08:00
2018-03-28 22:16:01 +02:00
Multiple applications can be served with one server:
2017-12-01 23:32:15 -08:00
```rust
2017-12-04 13:32:05 -08:00
# extern crate actix_web;
# extern crate tokio_core;
# use tokio_core::net::TcpStream;
# use std::net::SocketAddr;
2017-12-01 23:32:15 -08:00
use actix_web::*;
fn main() {
2018-02-10 11:01:54 -08:00
HttpServer::new(|| vec![
Application::new()
.prefix("/app1")
2018-03-01 19:12:59 -08:00
.resource("/", |r| r.f(|r| httpcodes::HttpOk)),
Application::new()
.prefix("/app2")
2018-03-01 19:12:59 -08:00
.resource("/", |r| r.f(|r| httpcodes::HttpOk)),
Application::new()
2018-03-01 19:12:59 -08:00
.resource("/", |r| r.f(|r| httpcodes::HttpOk)),
2017-12-01 23:32:15 -08:00
]);
}
```
2018-03-28 22:16:01 +02:00
All `/app1` requests route to the first application, `/app2` to the second and then all other to the third.
Applications get matched based on registration order, if an application with more general
prefix is registered before a less generic one, that would effectively block the less generic
application from getting matched. For example, if *application* with prefix "/" gets registered
as first application, it would match all incoming requests.
2017-12-13 21:38:47 -08:00
## State
2018-03-28 22:16:01 +02:00
Application state is shared with all routes and resources within the same application.
State can be accessed with the `HttpRequest::state()` method as a read-only,
but an interior mutability pattern with `RefCell` can be used to achieve state mutability.
State can be accessed with `HttpContext::state()` when using an http actor.
State is also available for route matching predicates and middlewares.
2017-12-13 21:38:47 -08:00
2018-03-28 22:16:01 +02:00
Let's write a simple application that uses shared state. We are going to store request count
2017-12-26 19:59:41 -08:00
in the state:
2017-12-13 21:38:47 -08:00
```rust
# extern crate actix;
# extern crate actix_web;
2017-12-26 19:59:41 -08:00
#
2017-12-13 21:38:47 -08:00
use std::cell::Cell;
2018-03-30 17:31:18 -07:00
use actix_web::{Application, HttpRequest, http};
2017-12-13 21:38:47 -08:00
// This struct represents state
struct AppState {
counter: Cell<usize>,
}
fn index(req: HttpRequest<AppState>) -> String {
let count = req.state().counter.get() + 1; // <- get count
req.state().counter.set(count); // <- store new count in state
format!("Request number: {}", count) // <- response with count
}
fn main() {
Application::with_state(AppState{counter: Cell::new(0)})
2018-03-30 17:31:18 -07:00
.resource("/", |r| r.method(http::Method::GET).f(index))
2017-12-13 21:38:47 -08:00
.finish();
}
```
2018-03-28 22:16:01 +02:00
Note on application state, http server accepts an application factory rather than an application
instance. Http server constructs an application instance for each thread, so application state
must be constructed multiple times. If you want to share state between different threads, a
2017-12-13 21:38:47 -08:00
shared object should be used, like `Arc`. Application state does not need to be `Send` and `Sync`
2018-03-28 22:16:01 +02:00
but the application factory must be `Send` + `Sync`.