使用 actix_web 对部分结构进行 Serde 反序列化
Serde deserialization of partial structs with actix_web
我有一个 API 端点,它利用 actix_web
反序列化传入的 JSON 有效负载(actix_web
最终使用 serde
作为 JSON反序列化)。
例如,我有这样的东西:
pub struct IncomingPayload {
pub field1: i32,
pub field2: String
}
pub async fn update_platforms(
pool: web::Data<Pool>,
req: web::Json<Vec<IncomingPayload>>,
) -> Result<HttpResponse, error::Error> {
println!(req.field1); // will be an i32
println!(req.field2); // will be a String
}
目前,只有 return 如果 serde
能够反序列化结构的所有字段,此端点才会成功。 IE。请求必须包含 field1
和 field2
键。
例如这将是成功的:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"field1": 1,"field2":"something"}' \
http://localhost:8080
但这不会(因为有效负载中缺少 field2
):
curl --header "Content-Type: application/json" \
--request POST \
--data '{"field1": 1}' \
http://localhost:8080
所以我的问题是,这可以做到吗?能否将带有键值字段子集的 JSON 有效负载发送到期望所有字段都存在的 actix_web
端点?
或者更确切地说,是否有一种通用方法可以使用 actix_web
或 serde
反序列化部分结构?
您可以使用 Option<T>
作为字段的类型,使其成为可选字段。如果在反序列化过程中缺少某个字段,则该字段设置为None
,否则设置为Some(value)
.
#[derive(Deserialize)]
struct IncomingPayload {
pub field1: Option<i32>,
pub field2: Option<String>,
}
对于实现 Default
的类型,如果字段缺失,您还可以使用 #[serde(default)]
将字段设置为默认值。
#[derive(Deserialize)]
struct IncomingPayload {
#[serde(default)] // default = 0
pub field1: i32,
#[serde(default)] // default = empty string
pub field2: String,
}
我有一个 API 端点,它利用 actix_web
反序列化传入的 JSON 有效负载(actix_web
最终使用 serde
作为 JSON反序列化)。
例如,我有这样的东西:
pub struct IncomingPayload {
pub field1: i32,
pub field2: String
}
pub async fn update_platforms(
pool: web::Data<Pool>,
req: web::Json<Vec<IncomingPayload>>,
) -> Result<HttpResponse, error::Error> {
println!(req.field1); // will be an i32
println!(req.field2); // will be a String
}
目前,只有 return 如果 serde
能够反序列化结构的所有字段,此端点才会成功。 IE。请求必须包含 field1
和 field2
键。
例如这将是成功的:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"field1": 1,"field2":"something"}' \
http://localhost:8080
但这不会(因为有效负载中缺少 field2
):
curl --header "Content-Type: application/json" \
--request POST \
--data '{"field1": 1}' \
http://localhost:8080
所以我的问题是,这可以做到吗?能否将带有键值字段子集的 JSON 有效负载发送到期望所有字段都存在的 actix_web
端点?
或者更确切地说,是否有一种通用方法可以使用 actix_web
或 serde
反序列化部分结构?
您可以使用 Option<T>
作为字段的类型,使其成为可选字段。如果在反序列化过程中缺少某个字段,则该字段设置为None
,否则设置为Some(value)
.
#[derive(Deserialize)]
struct IncomingPayload {
pub field1: Option<i32>,
pub field2: Option<String>,
}
对于实现 Default
的类型,如果字段缺失,您还可以使用 #[serde(default)]
将字段设置为默认值。
#[derive(Deserialize)]
struct IncomingPayload {
#[serde(default)] // default = 0
pub field1: i32,
#[serde(default)] // default = empty string
pub field2: String,
}