Reputation: 653
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.
Upvotes: 31
Views: 20213
Reputation: 14621
If you need default query parameters you can define them with the following code:
use actix_web::{App, get, HttpResponse, HttpServer, Responder, web, HttpRequest};
...
#[derive(Debug, Deserialize)]
pub struct Params {
orgIds: String
}
...
async fn totd(db_pool: web::Data<Pool>, req: HttpRequest) -> impl Responder {
let params = web::Query::<Params>::from_query(req.query_string())
.unwrap_or(web::Query(Params { orgIds: String::from("2") }));
let org_ids = ¶ms.orgIds;
...
This applies to actix-web = "4"
Alternatively you can also use Query::<HashMap<String, String>>::from_query
to parse the query.
Here is an example using from_query
:
let params = Query::<HashMap<String, String>>::from_query(req.query_string())
.unwrap();
let default_org_id = &String::from("2");
let default_lang = &String::from("en");
let org_ids = params.get("orgIds").unwrap_or(default_org_id);
let lang = params.get("lang").unwrap_or(default_lang);
With this second technique it is easier to deal with default values.
Upvotes: 2
Reputation: 121
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.
Upvotes: 11
Reputation: 1141
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 Option
s.
username: Option<String>
You can also use multiple web::Query<SomeType>
parameters in a handler.
Upvotes: 36
Reputation: 653
This is for actix-web v0.7
I managed to get it work by using:
let name = req.query().get("name").unwrap(); // name = "ferret"
Upvotes: 5