1
0
mirror of https://github.com/actix/actix-website synced 2024-11-24 08:43:01 +01:00
actix-website/content/docs/handlers.md

95 lines
3.2 KiB
Markdown
Raw Normal View History

2018-05-22 23:15:08 +02:00
---
title: Handlers
menu: docs_basics
weight: 160
---
# Request Handlers
2019-06-20 08:04:22 +02:00
A request handler is a function that accepts zero or more parameters that can be extracted
from a request (ie,
[*impl FromRequest*](https://docs.rs/actix-web/1.0.2/actix_web/trait.FromRequest.html))
and returns a type that can be converted into an HttpResponse (ie,
[*impl Responder*](https://docs.rs/actix-web/1.0.2/actix_web/trait.Responder.html)).
2018-05-22 23:15:08 +02:00
Request handling happens in two stages. First the handler object is called,
returning any object that implements the
2019-06-20 08:04:22 +02:00
[*Responder*](https://docs.rs/actix-web/1.0.2/actix_web/trait.Responder.html) trait.
Then, `respond_to()` is called on the returned object, converting itself to a `HttpResponse`
or `Error`.
2018-05-22 23:15:08 +02:00
By default actix provides `Responder` implementations for some standard types,
such as `&'static str`, `String`, etc.
> For a complete list of implementations, check
> [*Responder documentation*](../../actix-web/actix_web/trait.Responder.html#foreign-impls).
Examples of valid handlers:
```rust
2018-07-21 14:40:42 +02:00
fn index(req: &HttpRequest) -> &'static str {
2018-05-22 23:15:08 +02:00
"Hello world!"
}
```
```rust
2019-06-20 08:04:22 +02:00
fn index(req: HttpRequest) -> String {
2018-05-22 23:15:08 +02:00
"Hello world!".to_owned()
}
```
You can also change the signature to return `impl Responder` which works well if more
complex types are involved.
```rust
2019-06-20 08:04:22 +02:00
fn index(req: HttpRequest) -> impl Responder {
2018-05-22 23:15:08 +02:00
Bytes::from_static("Hello world!")
}
```
2019-06-20 08:04:22 +02:00
```rust
fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
2018-05-22 23:15:08 +02:00
...
}
```
## Response with custom type
To return a custom type directly from a handler function, the type needs to implement the `Responder` trait.
Let's create a response for a custom type that serializes to an `application/json` response:
2019-06-20 08:04:22 +02:00
{{< include-example example="responder-trait" file="main.rs" section="responder-trait" >}}
2018-05-22 23:15:08 +02:00
## Async handlers
There are two different types of async handlers. Response objects can be generated asynchronously
or more precisely, any type that implements the [*Responder*](../../actix-web/actix_web/trait.Responder.html) trait.
In this case, the handler must return a `Future` object that resolves to the *Responder* type, i.e:
2019-06-20 08:04:22 +02:00
{{< include-example example="async-handlers" file="main.rs" section="async-responder" >}}
2018-05-22 23:15:08 +02:00
Or the response body can be generated asynchronously. In this case, body
must implement the stream trait `Stream<Item=Bytes, Error=Error>`, i.e:
2019-06-20 08:04:22 +02:00
{{< include-example example="async-handlers" file="stream.rs" section="stream" >}}
2018-05-22 23:15:08 +02:00
Both methods can be combined. (i.e Async response with streaming body)
It is possible to return a `Result` where the `Result::Item` type can be `Future`.
In this example, the `index` handler can return an error immediately or return a
future that resolves to a `HttpResponse`.
2019-06-20 08:04:22 +02:00
{{< include-example example="async-handlers" file="async_stream.rs" section="async-stream" >}}
2018-05-22 23:15:08 +02:00
## Different return types (Either)
Sometimes, you need to return different types of responses. For example,
you can error check and return errors, return async responses, or any result that requires two different types.
For this case, the [*Either*](../../actix-web/actix_web/enum.Either.html) type can be used.
`Either` allows combining two different responder types into a single type.
2019-06-20 08:04:22 +02:00
{{< include-example example="either" file="main.rs" section="either" >}}