1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-24 07:53:00 +01:00

missing files

This commit is contained in:
Nikolay Kim 2017-12-01 23:42:21 -08:00
parent 1a5df7192e
commit 0dae109172
3 changed files with 286 additions and 0 deletions

143
guide/src/qs_4.md Normal file
View File

@ -0,0 +1,143 @@
# Handler
A request handler can by any object that implements
[`Handler` trait](../actix_web/struct.HttpResponse.html#implementations).
By default actix provdes several `Handler` implementations:
* Simple function that accepts `HttpRequest` and returns any object that
can be converted to `HttpResponse`
* Function that accepts `HttpRequest` and returns `Result<Reply, Into<Error>>` object.
* Function that accepts `HttpRequest` and return actor that has `HttpContext<A>`as a context.
Actix provides response conversion into `HttpResponse` for some standard types,
like `&'static str`, `String`, etc.
For complete list of implementations check
[HttpResponse documentation](../actix_web/struct.HttpResponse.html#implementations).
Examples:
```rust,ignore
fn index(req: HttpRequest) -> &'static str {
"Hello world!"
}
```
```rust,ignore
fn index(req: HttpRequest) -> String {
"Hello world!".to_owned()
}
```
```rust,ignore
fn index(req: HttpRequest) -> Bytes {
Bytes::from_static("Hello world!")
}
```
```rust,ignore
fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
...
}
```
## Custom conversion
Let's create response for custom type that serializes to `application/json` response:
```rust
extern crate actix;
extern crate actix_web;
extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;
use actix_web::*;
#[derive(Serialize)]
struct MyObj {
name: String,
}
/// we have to convert Error into HttpResponse as well, but with
/// specialization this could be handled genericly.
impl Into<HttpResponse> for MyObj {
fn into(self) -> HttpResponse {
let body = match serde_json::to_string(&self) {
Err(err) => return Error::from(err).into(),
Ok(body) => body,
};
// Create response and set content type
HttpResponse::Ok()
.content_type("application/json")
.body(body).unwrap()
}
}
fn main() {
let sys = actix::System::new("example");
HttpServer::new(
Application::default("/")
.resource("/", |r| r.handler(
Method::GET, |req| {MyObj{name: "user".to_owned()}})))
.serve::<_, ()>("127.0.0.1:8088").unwrap();
println!("Started http server: 127.0.0.1:8088");
actix::Arbiter::system().send(actix::msgs::SystemExit(0)); // <- remove this line, this code stops system during testing
let _ = sys.run();
}
```
If `specialization` is enabled, conversion could be simplier:
```rust,ignore
impl Into<Result<HttpResponse>> for MyObj {
fn into(self) -> Result<HttpResponse> {
let body = serde_json::to_string(&self)?;
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(body)?)
}
}
```
## Async handlers
There are two different types of async handlers.
Response object could be generated asynchronously. In this case handle must
return `Future` object that resolves to `HttpResponse`, i.e:
```rust,ignore
fn index(req: HttpRequest) -> Box<Future<HttpResponse, Error>> {
...
}
```
This handler can be registered with `ApplicationBuilder::async()` and
`Resource::async()` methods.
Or response body can be generated asynchronously. In this case body
must implement stream trait `Stream<Item=Bytes, Error=Error>`, i.e:
```rust,ignore
fn index(req: HttpRequest) -> HttpResponse {
let body: Box<Stream<Item=Bytes, Error=Error>> = Box::new(SomeStream::new());
HttpResponse::Ok().
.content_type("application/json")
.body(Body::Streaming(body)).unwrap()
}
fn main() {
Application::default("/")
.async("/async", index)
.finish();
}
```
Both methods could be combined. (i.e Async response with streaming body)

107
guide/src/qs_5.md Normal file
View File

@ -0,0 +1,107 @@
# Resources and Routes
All resources and routes register for specific application.
Application routes incoming requests based on route criteria which is defined during
resource registration or path prefix for simple handlers.
Internally *router* is a list of *resources*. Resource is an entry in *route table*
which corresponds to requested URL.
Prefix handler:
```rust,ignore
fn index(req: Httprequest) -> HttpResponse {
...
}
fn main() {
Application::default("/")
.handler("/prefix", |req| index)
.finish();
}
```
In this example `index` get called for any url which starts with `/prefix`.
Application prefix combines with handler prefix i.e
```rust,ignore
fn main() {
Application::default("/app")
.handler("/prefix", |req| index)
.finish();
}
```
In this example `index` get called for any url which starts with`/app/prefix`.
Resource contains set of route for same endpoint. Route corresponds to handling
*HTTP method* by calling *web handler*. Resource select route based on *http method*,
if no route could be matched default response `HTTPMethodNotAllowed` get resturned.
```rust,ignore
fn main() {
Application::default("/")
.resource("/prefix", |r| {
r.get(HTTPOk)
r.post(HTTPForbidden)
})
.finish();
}
```
[`ApplicationBuilder::resource()` method](../actix_web/dev/struct.ApplicationBuilder.html#method.resource)
accepts configuration function, resource could be configured at once.
Check [`Resource`](../actix-web/target/doc/actix_web/struct.Resource.html) documentation
for more information.
## Variable resources
Resource may have *variable path*also. For instance, a resource with the
path '/a/{name}/c' would match all incoming requests with paths such
as '/a/b/c', '/a/1/c', and '/a/etc/c'.
A *variable part*is specified in the form {identifier}, where the identifier can be
used later in a request handler to access the matched value for that part. This is
done by looking up the identifier in the `HttpRequest.match_info` object:
```rust
extern crate actix;
use actix_web::*;
fn index(req: Httprequest) -> String {
format!("Hello, {}", req.match_info.get('name').unwrap())
}
fn main() {
Application::default("/")
.resource("/{name}", |r| r.get(index))
.finish();
}
```
By default, each part matches the regular expression `[^{}/]+`.
You can also specify a custom regex in the form `{identifier:regex}`:
```rust,ignore
fn main() {
Application::default("/")
.resource(r"{name:\d+}", |r| r.get(index))
.finish();
}
```
To match path tail, `{tail:*}` pattern could be used. Tail pattern has to be last
segment in path otherwise it panics.
```rust,ignore
fn main() {
Application::default("/")
.resource(r"/test/{tail:*}", |r| r.get(index))
.finish();
}
```
Above example would match all incoming requests with path such as
'/test/b/c', '/test/index.html', and '/test/etc/test'.

36
guide/src/qs_6.md Normal file
View File

@ -0,0 +1,36 @@
# Application state
Application state is shared with all routes within same application.
State could be accessed with `HttpRequest::state()` method. It is read-only
but interior mutability pattern with `RefCell` could be used to archive state mutability.
State could be accessed with `HttpRequest::state()` method or
`HttpContext::state()` in case of http actor.
Let's write simple application that uses shared state. We are going to store requests count
in the state:
```rust
extern crate actix;
extern crate actix_web;
use std::cell::Cell;
use actix_web::*;
// 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::build("/", AppState{counter: Cell::new(0)})
.resource("/", |r| r.handler(Method::GET, index))
.finish();
}
```