0

i am current trying to make i api in actix web and get the current params of the url

my current ApiParams

#[serde_with::skip_serializing_none]
#[derive(Debug,Serialize,Deserialize)]
pub struct ApiParams {
    pub name: Option<String>,
    pub fname: Option<String>,
    pub categories: Option<Vec<String>>
}

impl std::fmt::Display for ApiParams {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let a = serde_json::to_string_pretty(&self).unwrap();
        write!(f, "{}", a)
    }
}

when i go to the http://localhost:1000/api/v1/?name=2&fname=21works but when i add the param categories, like http...v1/?name=2&categories=121 the program responde with:

Query deserialize error: invalid type: string "121", expected a sequence

#[get("/")]
pub async fn index(web::Query(params): web::Query<ApiParams>) ->  impl Responder {
    println!("{}", params);
    HttpResponse::Ok().content_type("application/json").json(json!({"test": "test"}))
}

Try to search in actix web documentation for a Vec but i didnt find it

i am expecting that categories should be a Vec/List of categories when i got to &categories=1,2or at least&categories=1&categories=2

Jmb
  • 18,893
  • 2
  • 28
  • 55

1 Answers1

1

You can accept lists in the form &categories=1,2 by changing your deserialization code. serde_with::StringWithSeparator provides ways to parse a String into multiple elements. The first argument allows for different separators, i.e., , or ;.

use serde_with::{StringWithSeparator, formats::CommaSeparator};

#[serde_with::serde_as]
#[serde_with::skip_serializing_none]
#[derive(Debug,Serialize,Deserialize)]
pub struct ApiParams {
    pub name: Option<String>,
    pub fname: Option<String>,
    #[serde_as(as = "Option<StringWithSeparator::<CommaSeparator, String>>")]
    pub categories: Option<Vec<String>>
}
jonasbb
  • 2,131
  • 1
  • 6
  • 25