Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uri.setQueryParams() doesn't seem to overwrite existing params #7106

Open
invadergir opened this issue May 8, 2023 · 4 comments
Open

Uri.setQueryParams() doesn't seem to overwrite existing params #7106

invadergir opened this issue May 8, 2023 · 4 comments
Labels
bug Determined to be a bug in http4s uri raze it and salt the earth whence it grew

Comments

@invadergir
Copy link

Hi, I was attempting to use Uri.setQueryParams() and noticed it doesn't behave according to the comments:

  /** Creates maybe a new `Self` with the specified parameters. The entire
    * [[Query]] will be replaced with the given one.
    */

This munit test passes on 0.23.19-RC3 and 0.23.4 (in a test project that imports http4s), and I would expect it to fail:

  test("setQueryParams() will overwrite any existing query parameters if they exist") {
    val uri = Uri.unsafeFromString("http://example.com/a/b/c?m=5&n=6")
    val origQP = Map("m" -> Seq("5"), "n" -> Seq("6"))
    assertEquals(uri.query.multiParams, origQP)

    val uriSetQP = uri.setQueryParams(Map("X" -> Seq("10")))
    val reallyExpected = Map("X" -> Seq("10")) // we only expect the new QPs to be set, the others lost
    val expected = origQP ++ reallyExpected  // this is what we actually get, see below:
    assertEquals(uriSetQP.query.multiParams, expected )
}
@armanbilge armanbilge added uri raze it and salt the earth whence it grew bug Determined to be a bug in http4s labels May 9, 2023
@armanbilge
Copy link
Member

Thanks! I guess the bug is here?

val vec = params.foldLeft(query.toVector) {

@danicheg
Copy link
Member

danicheg commented May 9, 2023

My humble opinion is that we better need to fix the scaladoc and add a new method rather than change the behaviour of that function.

@armanbilge
Copy link
Member

Yeah, I wouldn't disagree. It looks like it's been working this way since v0.20.0. dd7e192

@satorg
Copy link
Contributor

satorg commented May 9, 2023

Just fyi: there's another method that modifies query parameters in Uri: withQueryParams:

scala> val uri = uri"https://typelevel.org?foo=123&bar=456"
val uri: org.http4s.Uri = https://typelevel.org?foo=123&bar=456

scala> uri.setQueryParams(Map("bar" -> Seq("789"), "car" -> Seq("abc")))
val res2: org.http4s.Uri = https://typelevel.org?foo=123&bar=456&bar=789&car=abc

scala> uri.withQueryParams(Map("bar" -> "789", "car" -> "abc"))
val res4: org.http4s.Uri = https://typelevel.org?foo=123&bar=789&car=abc

So neither of those two methods does replace query parameters completely.
It seems that the only way to get them replaced is uri.copy(query = ...), which may not be that bad but...

Now compare to a Request's header methods:

  • withHeadersreplaces all the headers in a request.
  • putHeaders – actually, just adds given headers to existing ones.
  • addHeader – does the same thing as putHeaders but just for a single header.

So in my opinion, current naming conventions in the library are quite confusing and inconsistent.

  • withSomething – may or may not replace everything;
  • setSomething – despite its name, may append stuff instead of replacing it;
  • putSomething, addSomething – well, not always obvious from their names too.

Moreover, although the withSomething version is quite ubiquitous, but it may have different behavior. Whereas other names like set, put, add, etc may or may not exist in every particular model.

Perhaps, it would be nice if the naming consistency could be addressed in 1.x version at least, wdyt?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Determined to be a bug in http4s uri raze it and salt the earth whence it grew
Projects
None yet
Development

No branches or pull requests

4 participants