2018-05-22 23:15:08 +02:00
|
|
|
---
|
|
|
|
title: Extractors
|
|
|
|
menu: docs_basics
|
|
|
|
weight: 170
|
|
|
|
---
|
|
|
|
|
|
|
|
# Type-safe information extraction
|
|
|
|
|
2019-06-20 10:20:12 +02:00
|
|
|
Actix-web provides a facility for type-safe request information access called *extractors*
|
|
|
|
(ie, `impl FromRequest`). By default, actix-web provides several extractor implementations.
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2020-05-25 08:51:38 +02:00
|
|
|
An extractor can be accessed as an argument to a handler function. Actix-web supports
|
2020-01-02 13:33:33 +01:00
|
|
|
up to 10 extractors per handler function. Argument position does not matter.
|
2018-05-25 21:51:16 +02:00
|
|
|
|
2019-06-20 10:20:12 +02:00
|
|
|
{{< include-example example="extractors" file="main.rs" section="option-one" >}}
|
2018-05-25 21:51:16 +02:00
|
|
|
|
2018-05-22 23:15:08 +02:00
|
|
|
# Path
|
|
|
|
|
2019-06-25 05:36:32 +02:00
|
|
|
[*Path*][pathstruct] provides information that can be extracted from the Request's
|
|
|
|
path. You can deserialize any variable segment from the path.
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2020-05-25 08:51:38 +02:00
|
|
|
For instance, for resource that registered for the `/users/{userid}/{friend}` path,
|
2019-06-25 05:36:32 +02:00
|
|
|
two segments could be deserialized, `userid` and `friend`. These segments could be
|
|
|
|
extracted into a `tuple`, i.e. `Path<(u32, String)>` or any structure that implements
|
|
|
|
the `Deserialize` trait from the *serde* crate.
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2019-06-17 05:17:17 +02:00
|
|
|
{{< include-example example="extractors" file="path_one.rs" section="path-one" >}}
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2019-06-25 05:36:32 +02:00
|
|
|
It is also possible to extract path information to a specific type that implements the
|
|
|
|
`Deserialize` trait from *serde*. Here is an equivalent example that uses *serde*
|
2018-06-01 17:11:25 +02:00
|
|
|
instead of a *tuple* type.
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2019-06-17 05:17:17 +02:00
|
|
|
{{< include-example example="extractors" file="path_two.rs" section="path-two" >}}
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2019-06-20 10:20:12 +02:00
|
|
|
It is also possible to `get` or `query` the request for path parameters by name:
|
|
|
|
|
|
|
|
{{< include-example example="extractors" file="path_three.rs" section="path-three" >}}
|
|
|
|
|
2018-05-22 23:15:08 +02:00
|
|
|
# Query
|
|
|
|
|
2019-06-25 05:36:32 +02:00
|
|
|
The [*Query*][querystruct] type provides extraction functionality for the request's
|
|
|
|
query parameters. Underneath it uses *serde_urlencoded* crate.
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2019-06-17 05:17:17 +02:00
|
|
|
{{< include-example example="extractors" file="query.rs" section="query" >}}
|
2018-05-22 23:15:08 +02:00
|
|
|
|
|
|
|
# Json
|
|
|
|
|
2020-05-25 08:51:38 +02:00
|
|
|
[*Json*][jsonstruct] allows deserialization of a request body into a struct. To extract
|
2019-06-25 05:36:32 +02:00
|
|
|
typed information from a request's body, the type `T` must implement the `Deserialize`
|
|
|
|
trait from *serde*.
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2019-06-17 05:17:17 +02:00
|
|
|
{{< include-example example="extractors" file="json_one.rs" section="json-one" >}}
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2018-06-01 17:11:25 +02:00
|
|
|
Some extractors provide a way to configure the extraction process. Json extractor
|
2020-05-25 08:51:38 +02:00
|
|
|
[*JsonConfig*][jsonconfig] type for configuration. To configure an extractor, pass its
|
2019-06-25 05:36:32 +02:00
|
|
|
configuration object to the resource's `.data()` method. In case of a *Json* extractor
|
|
|
|
it returns a *JsonConfig*. You can configure the maximum size of the json payload as
|
|
|
|
well as a custom error handler function.
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2018-06-28 02:24:48 +02:00
|
|
|
The following example limits the size of the payload to 4kb and uses a custom error handler.
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2019-06-17 05:17:17 +02:00
|
|
|
{{< include-example example="extractors" file="json_two.rs" section="json-two" >}}
|
2018-05-22 23:15:08 +02:00
|
|
|
|
|
|
|
# Form
|
|
|
|
|
2020-05-25 08:51:38 +02:00
|
|
|
At the moment, only url-encoded forms are supported. The url-encoded body could be
|
2019-06-25 05:36:32 +02:00
|
|
|
extracted to a specific type. This type must implement the `Deserialize` trait from
|
|
|
|
the *serde* crate.
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2019-06-25 05:36:32 +02:00
|
|
|
[*FormConfig*][formconfig] allows configuring the extraction process.
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2019-06-17 05:17:17 +02:00
|
|
|
{{< include-example example="extractors" file="form.rs" section="form" >}}
|
2018-05-22 23:15:08 +02:00
|
|
|
|
|
|
|
# Other
|
|
|
|
|
2019-06-20 10:20:12 +02:00
|
|
|
Actix-web also provides several other extractors:
|
2018-05-22 23:15:08 +02:00
|
|
|
|
2019-06-25 05:36:32 +02:00
|
|
|
* [*Data*][datastruct] - If you need access to an application state.
|
|
|
|
* *HttpRequest* - *HttpRequest* itself is an extractor which returns self, in case you
|
|
|
|
need access to the request.
|
|
|
|
* *String* - You can convert a request's payload to a *String*. [*Example*][stringexample]
|
2018-05-22 23:15:08 +02:00
|
|
|
is available in doc strings.
|
2018-06-01 17:11:25 +02:00
|
|
|
* *bytes::Bytes* - You can convert a request's payload into *Bytes*.
|
2019-06-25 05:36:32 +02:00
|
|
|
[*Example*][bytesexample]
|
2018-05-22 23:15:08 +02:00
|
|
|
is available in doc strings.
|
2019-06-20 10:20:12 +02:00
|
|
|
* *Payload* - You can access a request's payload.
|
2019-06-25 05:36:32 +02:00
|
|
|
[*Example*][payloadexample]
|
2019-06-20 10:20:12 +02:00
|
|
|
|
2020-01-02 13:33:33 +01:00
|
|
|
# Application state extractor
|
2019-06-20 10:20:12 +02:00
|
|
|
|
|
|
|
Application state is accessible from the handler with the `web::Data` extractor;
|
|
|
|
however, state is accessible as a read-only reference. If you need mutable access to state,
|
|
|
|
it must be implemented.
|
|
|
|
|
2020-05-25 08:51:38 +02:00
|
|
|
> **Beware**, actix creates multiple copies of the application state and the handlers. It creates
|
|
|
|
> one copy for each thread.
|
2019-06-20 10:20:12 +02:00
|
|
|
|
|
|
|
Here is an example of a handler that stores the number of processed requests:
|
|
|
|
|
|
|
|
{{< include-example example="request-handlers" file="main.rs" section="data" >}}
|
|
|
|
|
|
|
|
Although this handler will work, `self.0` will be different depending on the number of threads and
|
|
|
|
number of requests processed per thread. A proper implementation would use `Arc` and `AtomicUsize`.
|
|
|
|
|
|
|
|
{{< include-example example="request-handlers" file="handlers_arc.rs" section="arc" >}}
|
|
|
|
|
|
|
|
> Be careful with synchronization primitives like `Mutex` or `RwLock`. The `actix-web` framework
|
|
|
|
> handles requests asynchronously. By blocking thread execution, all concurrent
|
|
|
|
> request handling processes would block. If you need to share or update some state
|
2020-01-02 13:33:33 +01:00
|
|
|
> from multiple threads, consider using the tokio synchronization primitives.
|
2019-06-25 05:36:32 +02:00
|
|
|
|
2019-12-28 16:38:07 +01:00
|
|
|
[pathstruct]: https://docs.rs/actix-web/2/actix_web/dev/struct.Path.html
|
|
|
|
[querystruct]: https://docs.rs/actix-web/2/actix_web/web/struct.Query.html
|
|
|
|
[jsonstruct]: https://docs.rs/actix-web/2/actix_web/web/struct.Json.html
|
|
|
|
[jsonconfig]: https://docs.rs/actix-web/2/actix_web/web/struct.JsonConfig.html
|
|
|
|
[formconfig]: https://docs.rs/actix-web/2/actix_web/web/struct.FormConfig.html
|
|
|
|
[datastruct]: https://docs.rs/actix-web/2/actix_web/web/struct.Data.html
|
|
|
|
[stringexample]: https://docs.rs/actix-web/2/actix_web/trait.FromRequest.html#example-2
|
|
|
|
[bytesexample]: https://docs.rs/actix-web/2/actix_web/trait.FromRequest.html#example-4
|
|
|
|
[payloadexample]: https://docs.rs/actix-web/2/actix_web/web/struct.Payload.html
|
2019-06-25 05:36:32 +02:00
|
|
|
[actix]: https://actix.github.io/actix/actix/
|