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

97 lines
5.5 KiB
Markdown
Raw Normal View History

2018-05-22 23:15:08 +02:00
---
title: Extractors
menu: docs_basics
weight: 170
---
# Type-safe information extraction
2022-02-26 05:41:49 +01:00
Actix-web provides a facility for type-safe request information access called _extractors_ (i.e., `impl FromRequest`). By default, actix-web provides several extractor implementations.
2018-05-22 23:15:08 +02:00
2022-02-26 05:41:49 +01:00
An extractor can be accessed as an argument to a handler function. Actix-web supports up to 12 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
2022-02-26 05:41:49 +01: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
2022-02-26 05:41:49 +01:00
For instance, for resource that registered for the `/users/{user_id}/{friend}` path, two segments could be deserialized, `user_id` 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
2022-02-26 05:41:49 +01: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_ 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
2022-02-26 05:41:49 +01: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
2022-02-26 05:41:49 +01:00
[_Json_][jsonstruct] allows deserialization of a request body into a struct. To extract 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
2022-02-26 05:41:49 +01:00
Some extractors provide a way to configure the extraction process. To configure an extractor, pass its configuration object to the resource's `.data()` method. In the case of _Json_ extractor it returns a [_JsonConfig_][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
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
2022-02-26 05:41:49 +01:00
At the moment, only url-encoded forms are supported. The url-encoded body could be extracted to a specific type. This type must implement the `Deserialize` trait from the _serde_ crate.
2018-05-22 23:15:08 +02:00
2022-02-26 05:41:49 +01: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
2022-02-26 05:41:49 +01: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] is available in doc strings.
- _actix_web::web::Bytes_ - You can convert a request's payload into _Bytes_. [_Example_][bytesexample] is available in doc strings.
- _Payload_ - You can access a request's payload. [_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
2022-02-26 05:41:49 +01: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.
2019-06-20 10:20:12 +02:00
2022-02-26 05:41:49 +01: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" >}}
2022-02-26 05:41:49 +01:00
Although this handler will work, `data.count` will only count the number of requests handled _by each thread_. To count the number of total requests across all threads, one should use `Arc` and [atomics][atomics].
2019-06-20 10:20:12 +02:00
{{< include-example example="request-handlers" file="handlers_arc.rs" section="arc" >}}
2022-02-26 05:41:49 +01:00
> **Note**, if you want the _entire_ state to be shared across all threads, use `web::Data` and `app_data` as described in [Shared Mutable State][shared_mutable_state].
2022-02-26 05:41:49 +01:00
> 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 from multiple threads, consider using the tokio synchronization primitives.
2020-09-12 17:21:54 +02:00
[pathstruct]: https://docs.rs/actix-web/3/actix_web/dev/struct.Path.html
[querystruct]: https://docs.rs/actix-web/3/actix_web/web/struct.Query.html
[jsonstruct]: https://docs.rs/actix-web/3/actix_web/web/struct.Json.html
[jsonconfig]: https://docs.rs/actix-web/3/actix_web/web/struct.JsonConfig.html
[formconfig]: https://docs.rs/actix-web/3/actix_web/web/struct.FormConfig.html
[datastruct]: https://docs.rs/actix-web/3/actix_web/web/struct.Data.html
[stringexample]: https://docs.rs/actix-web/3/actix_web/trait.FromRequest.html#example-2
[bytesexample]: https://docs.rs/actix-web/3/actix_web/trait.FromRequest.html#example-4
[payloadexample]: https://docs.rs/actix-web/3/actix_web/web/struct.Payload.html
[actix]: https://actix.github.io/actix/actix/
[atomics]: https://doc.rust-lang.org/std/sync/atomic/
[shared_mutable_state]: ../application#shared-mutable-state