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

[BUG] ZioHttpInterpreter: Route with literal path segment makes route with variable path segment unavailable #3992

Closed
wwbakker opened this issue Aug 19, 2024 · 5 comments

Comments

@wwbakker
Copy link

Tapir version: Works in tapir 1.10.10 and before, broken since tapir 1.10.11 and later

Describe the bug

Consider the following code:

//> using dep com.softwaremill.sttp.tapir::tapir-zio-http-server::1.10.10

import zio.*
import zio.http.*
import sttp.tapir.generic.auto.*
import sttp.tapir.ztapir.*
import sttp.tapir.*
import sttp.tapir.server.ziohttp.ZioHttpInterpreter

object TestServer extends ZIOAppDefault with Tapir:

  val ep1 = endpoint.get.in("base" / "type1" / "fixed").out(stringBody)
  val ep2 = endpoint.get.in("base" / path[String]("type") / "dynamic").out(stringBody)
  val app = ZioHttpInterpreter()
    .toHttp(
      List(
        ep1.zServerLogic(_ => ZIO.succeed("Fixed endpoint - tapir 1.10.10")),
        ep2.zServerLogic(_ => ZIO.succeed("Dynamic endpoint - tapir 1.10.10"))
      )
    )

  override def run =
    Server
      .serve(app)
        .provideSomeLayer[Scope](
          ZLayer.succeed(Server.Config.default.port(8060)) >>> Server.live
        )

If I call the endpoints, both work as expected:

GET http://localhost:8060/base/type1/fixed

HTTP/1.1 200 OK
content-length: 30
Content-Type: text/plain; charset=UTF-8
date: Mon, 19 Aug 2024 13:47:23 GMT

Fixed endpoint - tapir 1.10.10

Response code: 200 (OK); Time: 231ms (231 ms); Content length: 30 bytes (30 B)
GET http://localhost:8060/base/type1/dynamic

HTTP/1.1 200 OK
content-length: 32
Content-Type: text/plain; charset=UTF-8
date: Mon, 19 Aug 2024 13:47:46 GMT

Dynamic endpoint - tapir 1.10.10

Response code: 200 (OK); Time: 16ms (16 ms); Content length: 32 bytes (32 B)

If I do the same with a newer version (same code, just versions changed):

//> using dep com.softwaremill.sttp.tapir::tapir-zio-http-server::1.11.1

import zio.*
import zio.http.*
import sttp.tapir.generic.auto.*
import sttp.tapir.ztapir.*
import sttp.tapir.*
import sttp.tapir.server.ziohttp.ZioHttpInterpreter

object TestServer extends ZIOAppDefault with Tapir:

  val ep1 = endpoint.get.in("base" / "type1" / "fixed").out(stringBody)
  val ep2 = endpoint.get.in("base" / path[String]("type") / "dynamic").out(stringBody)
  val app = ZioHttpInterpreter()
    .toHttp(
      List(
        ep1.zServerLogic(_ => ZIO.succeed("Fixed endpoint - tapir 1.11.1")),
        ep2.zServerLogic(_ => ZIO.succeed("Dynamic endpoint - tapir 1.11.1"))
      )
    )

  override def run =
    Server
      .serve(app)
        .provideSomeLayer[Scope](
          ZLayer.succeed(Server.Config.default.port(8060)) >>> Server.live
        )

If I call the endpoints, only the first one works:

GET http://localhost:8060/base/type1/fixed

HTTP/1.1 200 OK
content-length: 29
Content-Type: text/plain; charset=UTF-8
date: Mon, 19 Aug 2024 13:49:31 GMT

Fixed endpoint - tapir 1.11.1

Response code: 200 (OK); Time: 209ms (209 ms); Content length: 29 bytes (29 B)

GET http://localhost:8060/base/type1/dynamic

HTTP/1.1 404 Not Found
warning: 199 ZIO HTTP "/base/type1/dynamic"
date: Mon, 19 Aug 2024 13:50:01 GMT
content-length: 0

<Response body is empty>

Response code: 404 (Not Found); Time: 11ms (11 ms); Content length: 0 bytes (0 B)

Additional information
I also did some research into whether this might be a zio-http issue. I see however that when using tapir, the routing is done by ZioHttpInterpreter, instead of the routing code from zio-http itself.

The interesting/funny thing there is that zio-http has the same bug, but as far as I can tell it has never worked there. (zio/zio-http#3036)

My best guess is that the issue was introduced in this PR: #3856

@felix-hedenstrom
Copy link
Contributor

We've also observed this issue and it prevents us from upgrading beyond 1.10.10.

@felix-hedenstrom
Copy link
Contributor

I ran your example with 1.11.3 and it works now. Must have been fixed at some point.

@wwbakker
Copy link
Author

wwbakker commented Sep 17, 2024

That's good news. Seems to be fixed specifically in 1.11.3, because 1.11.2 still fails. Possibly the 3.0.0 zio-http support?

I will check in a real project hopefully later today, and if that fixes it I'll close the ticket.

@adamw
Copy link
Member

adamw commented Sep 17, 2024

I added a test, passes (at least locally). Let me know if there would be any more problems

@wwbakker
Copy link
Author

Works well now, thanks @adamw @felix-hedenstrom and the contributors to the 1.11.3!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants