http icon indicating copy to clipboard operation
http copied to clipboard

PathAndQuery should have a way to build Query Parameters

Open Firstyear opened this issue 3 years ago • 4 comments

When constructive a URI with https://docs.rs/http/0.2.4/http/uri/struct.PathAndQuery.html it's currently assumed that you already have the uri in a single string that contains both the path and query. However, applications may wish to build a query "as they go" specifying each key and value through a builder process.

Firstyear avatar Jul 12 '21 07:07 Firstyear

I agree that it would be nice to have discrete builder methods for both path and query.

It would help in situations where you are building an Uri with a constant scheme, authority and path, but changing query param. For example if you have a client which is making a search query to an API.

Currently you would have to do it something like this:

const AUTHORITY: &str = "api.website.com";
const PATH: &str = "/search";
fn search(username: &str) -> Result {
    let query = format!("user={}", username);
    let uri = Uri::builder()
        .scheme("https")
        .authority(AUTHORITY)
        .path_and_query(format!("{}?{}", PATH, query))
        .build()?;
    
    let response = client.get(uri);
    ...
} 

Instead if the builder had both path and query functions.

const AUTHORITY: &str = "api.website.com";
const PATH: &str = "/search";
fn search(username: &str) -> Result {
    let query = format!("user={}", username);
    let uri = Uri::builder()
        .scheme("https")
        .authority(AUTHORITY)
        .path(PATH)
        .query(query)
        .build()?;
    
    let response = client.get(uri);
    ...
} 

This would IMO make more sense anyway since the path and query parts aren't really linked any ways.

Also depending on the implementation users could also construct urls from path parts by calling path() multiple times, and same with query().

kallekankaanpaa avatar Nov 02 '21 11:11 kallekankaanpaa

Looking at the builder available in this library, I think what is really missing here is a PathAndQueryBuilder

This way, we will not have to update Uri::builder and we could have following code working:

const AUTHORITY: &str = "api.website.com";
const PATH: &str = "/search";

let uri = Uri::builder()
    .scheme("https")
    .authority(AUTHORITY)
    .path_and_query(
        PathAndQuery::builder()
            .path(PATH)
            .query("user", username)
            .query("other", "args")
            .build()
    )
    .build()
    .unwrap();

This builder may also be reusable in case full URI is not required, but just PathAndQuery is.

I can provide PR for this if anyone is interested about this.

arthurlm avatar Mar 22 '22 13:03 arthurlm

I am surprised that this is not a priority. Formatting query args manually is nearly a guaranteed way to shoot yourself in the foot.

pronebird avatar Apr 03 '24 12:04 pronebird

Use serde_html_form or serde_urlencoded or serde_qs. The http crate is still not the right place for building or decoding query strings.

robjtede avatar Apr 03 '24 13:04 robjtede