使用actix_web进行Serde部分结构反序列化

3

我有一个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
}

目前,只有当serde能够反序列化结构体的所有字段时,此端点才会成功返回。也就是说,请求必须包含field1field2键。

例如,以下请求将成功:

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_webserde反序列化此类部分结构体?

1个回答

8

如果要让一个字段是可选的,可以使用 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,
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接