Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I parse query strings in actix-web?

How can I parse the name and color arguments from the following URL using actix-web?

http://example.com/path/to/page?name=ferret&color=purple

I suppose my path should be /path/to/page and then when I try to query for name I receive an empty string (req.match_info().query("name") where req: &HttpRequest).

The only documentation I found is about matching names (e.g., if the path is /people/{page}/ it'll match /people/123/ such that page = 123 but that's not what I want.

like image 446
H. Desane Avatar asked Jan 28 '19 16:01

H. Desane


3 Answers

It looks like they removed the query function and just have a query_string function. You could use a crate for this called qstring:

use qstring::QString;
...
let query_str = req.query_string(); // "name=ferret"
let qs = QString::from(query_str);
let name = qs.get("name").unwrap(); // "ferret"

You could also use an extractor to deserialize the query params into a struct with Serde

use serde::Deserialize;

#[derive(Deserialize)]
struct Info {
    username: String,
}

fn index(info: web::Query<Info>) -> Result<String, actix_web::Error> {
    Ok(format!("Welcome {}!", info.username))
}

Note that the handler will only be called if the query username is actually present in the request. This would call the handler:

curl "http://localhost:5000?username=joe"

but these would not:

curl "http://localhost:5000"
curl "http://localhost:5000?password=blah"

If you need optional parameters, just make the properties in your struct Options.

username: Option<String>

You can also use multiple web::Query<SomeType> parameters in a handler.

like image 140
Rokit Avatar answered Nov 16 '22 12:11

Rokit


This is for actix-web v0.7

I managed to get it work by using:

let name = req.query().get("name").unwrap(); // name = "ferret"
like image 45
H. Desane Avatar answered Nov 16 '22 11:11

H. Desane


actix_web::web::query parses query strings:

use actix_web::{web, App};
use serde_derive::Deserialize;

#[derive(Debug, Deserialize)]
pub struct Params {
    name: String,
    color: String,
}

#[get("/path/to/page")]
async fn handler(req: HttpRequest) -> HttpResponse {
    let params = web::Query::<Params>::from_query(req.query_string()).unwrap();
    HttpResponse::Ok().body(format!("{:?}", params))
}

The official documentation has another example.

like image 3
pinsl Avatar answered Nov 16 '22 11:11

pinsl