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] SwaggerAkka can't be used with a path of more than one segment #694

Closed
kubukoz opened this issue Aug 5, 2020 · 0 comments
Closed

Comments

@kubukoz
Copy link
Contributor

kubukoz commented Aug 5, 2020

Tapir version: 0.16.10

Scala version: 2.12.12

Describe the bug

val path = "v1/docs"

new SwaggerAkka(docs.toYaml, path).routes

Using a route generated like that results in an invalid route: it doesn't match /v1/docs, but actually /v1/%2Fdocs (%2F, the urlencoded slash) - that's because SwaggerAkka is using pathPrefix(path) which accepts a PathMatcher, to which the string is converted as an entire segment.

When you go to /v1/%2Fdocs, however, you get a redirect to /v1/docs/index.html?url=/v1/docs/docs.yaml, which is still incorrect:

url --head localhost:8080/v1%2Fdocs                                                      
HTTP/1.1 308 Permanent Redirect
Location: /v1/docs/index.html?url=/v1/docs/docs.yaml
Server: akka-http/10.1.12
Date: Wed, 05 Aug 2020 23:33:26 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 128

How to reproduce?

libraryDependencies ++= Seq(
  "com.softwaremill.sttp.tapir" %% "tapir-akka-http-server" % "0.16.10",
  "com.softwaremill.sttp.tapir" %% "tapir-openapi-docs" % "0.16.10",
  "com.softwaremill.sttp.tapir" %% "tapir-openapi-circe-yaml" % "0.16.10",
  "com.softwaremill.sttp.tapir" %% "tapir-swagger-ui-akka-http" % "0.16.10"
)

scalaVersion := "2.12.12"
import java.nio.charset.StandardCharsets
import sttp.tapir.openapi.circe.yaml._
import sttp.tapir.openapi._
import sttp.tapir.docs.openapi._
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives
import akka.actor.ActorSystem
import akka.http.scaladsl.server.HttpApp
import sttp.tapir.swagger.akkahttp.SwaggerAkka
import sttp.tapir.server.akkahttp._
import scala.concurrent.Future

object Endpoints {
  import sttp.tapir._

  val randomEndpoint: Endpoint[Unit, Unit, String, Nothing] =
    endpoint.in("v1" / "hello").out(stringBody(StandardCharsets.UTF_8))

}
object Demo extends HttpApp with App {

  import Endpoints._

  val docs =
    randomEndpoint
      .toOpenAPI("my app", "0.0.1")

  val docsRoute = new SwaggerAkka(docs.toYaml, "v1/docs").routes
  val route = randomEndpoint.toRoute(_ => Future.successful(Right("witam")))

  override val routes = docsRoute // ~ route

  startServer("localhost", 8080)
}

then hit localhost:8080/v1/docs in your browser.

Additional information

This has been encountered by @CucumisSativus, so credits to him for finding this issue ;)

I think the simplest fix would be to either:

  • accept some PathMatcher[...] instead of a String (might be weird in types, haven't tried though)
  • not accept any string at all and create a route on the root level, thus requiring users to wrap the whole thing in a pathPrefix of their own
  • accept a list of segments and concatenate them with the right / operator.

I would personally opt for option 2, as it's the most flexible anyway. The existing implementation could be left as a deprecated overload for a while, then removed maybe in 0.17 or 1.0.

erikvanoosten pushed a commit to erikvanoosten/tapir that referenced this issue Nov 23, 2020
adamw added a commit that referenced this issue Dec 1, 2020
Allow swagger-ui to run on a non-root context-path. Solves #694.
@adamw adamw closed this as completed Mar 1, 2021
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

2 participants