5.7 KiB
title | menu | weight |
---|---|---|
Extractors | docs_basics | 170 |
Type-safe information extraction
Actix Web provides a facility for type-safe request information access called extractors (i.e., impl FromRequest
). There are lots of built-in extractor implementations (see implementors).
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.
{{< include-example example="extractors" file="main.rs" section="option-one" >}}
Path
Path provides information that is extracted from the request's path. Parts of the path that are extractable are called "dynamic segments" and are marked with curly braces. You can deserialize any variable segment from the path.
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 as a tuple in the order they are declared (e.g., Path<(u32, String)>
).
{{< include-example example="extractors" file="path_one.rs" section="path-one" >}}
It is also possible to extract path information to a type that implements the Deserialize
trait from serde
by matching dynamic segment names with field names. Here is an equivalent example that uses serde
instead of a tuple type.
{{< include-example example="extractors" file="path_two.rs" section="path-two" >}}
As a non-type-safe alternative, it's also possible to query
the request for path parameters by name within a handler:
{{< include-example example="extractors" file="path_three.rs" section="path-three" >}}
Query
The Query type provides extraction functionality for the request's query parameters. Underneath it uses serde_urlencoded crate.
{{< include-example example="extractors" file="query.rs" section="query" >}}
Json
Json 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.
{{< include-example example="extractors" file="json_one.rs" section="json-one" >}}
Some extractors provide a way to configure the extraction process. To configure an extractor, pass its configuration object to the resource's .app_data()
method. In the case of Json extractor it returns a JsonConfig. You can configure the maximum size of the JSON payload as well as a custom error handler function.
The following example limits the size of the payload to 4kb and uses a custom error handler.
{{< include-example example="extractors" file="json_two.rs" section="json-two" >}}
Form
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.
FormConfig allows configuring the extraction process.
{{< include-example example="extractors" file="form.rs" section="form" >}}
Other
Actix Web also provides several other extractors:
- Data - 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 is available in doc strings.
- actix_web::web::Bytes - You can convert a request's payload into Bytes. Example is available in doc strings.
- Payload - You can access a request's payload. Example
Application state extractor
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.
Beware, actix creates multiple copies of the application state and the handlers. It creates one copy for each thread.
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, 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.
{{< include-example example="request-handlers" file="handlers_arc.rs" section="arc" >}}
Note
, if you want the entire state to be shared across all threads, use
web::Data
andapp_data
as described in Shared Mutable State.
Be careful with synchronization primitives like
Mutex
orRwLock
. Theactix-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.