softwaremill / softwaremill/tapir
[BUG] RejectHandler doesn't works for Vertx web server
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 1.5k
- Forks
- 468
- Avg merge
- 5h 37m
- Merged PRs (30d)
- 34
Description
Tapir version: 1.11.49
Scala version: 2.13.1
Describe the bug
tapir reject handler doesn't works for Vertx web server
How to reproduce?
//> using scala 2.13.16
//> using dep org.typelevel::cats-effect:3.6.3
//> using dep com.softwaremill.sttp.tapir::tapir-vertx-server-cats:1.11.49
//> using dep com.softwaremill.sttp.tapir::tapir-http4s-server:1.11.49
//> using dep org.http4s::http4s-ember-server:0.23.32
import cats.effect._
import cats.effect.std.Dispatcher
import com.comcast.ip4s.Port
import io.vertx.core.Vertx
import io.vertx.ext.web.Router
import org.http4s.ember.server.EmberServerBuilder
import sttp.model.StatusCode
import sttp.tapir._
import sttp.tapir.server.ServerEndpoint
import sttp.tapir.server.http4s.{Http4sServerInterpreter, Http4sServerOptions}
import sttp.tapir.server.interceptor.CustomiseInterceptors
import sttp.tapir.server.interceptor.reject.DefaultRejectHandler
import sttp.tapir.server.model.ValuedEndpointOutput
import sttp.tapir.server.vertx.cats.VertxCatsServerInterpreter._
import sttp.tapir.server.vertx.cats.{VertxCatsServerInterpreter, VertxCatsServerOptions}
object App extends IOApp {
private val responseEndpoint: ServerEndpoint[Any, IO] =
endpoint
.get
.in("response")
.in(query[String]("key"))
.out(plainBody[String])
.serverLogicSuccessPure(req => s"Response: $req")
private val okEndpoint: ServerEndpoint[Any, IO] =
endpoint
.get
.in("ok")
.out(plainBody[String])
.serverLogicSuccessPure(_ => "OK")
private val endpoints: List[ServerEndpoint[Any, IO]] = List(responseEndpoint, okEndpoint)
private def addNotFoundHandler[O]: CustomiseInterceptors[IO, O] => CustomiseInterceptors[IO, O] =
_
.rejectHandler(
DefaultRejectHandler[IO](
(sc: StatusCode, m: String) => ValuedEndpointOutput(statusCode.and(stringBody), (sc, m)),
Some((StatusCode.Ok, "Custom Not Found Response"))
)
)
def runAsVertx: IO[Nothing] =
Dispatcher.parallel[IO].flatMap { dispatcher =>
Resource
.make(
IO.delay {
val vertx = Vertx.vertx()
val server = vertx.createHttpServer()
val router = Router.router(vertx)
val options =
addNotFoundHandler(VertxCatsServerOptions.customiseInterceptors[IO](dispatcher))
.options
endpoints.foreach(VertxCatsServerInterpreter[IO](options).route(_)(router))
server.requestHandler(router).listen(8080)
}.flatMap(_.asF[IO])
) { server =>
IO.delay(server.close).flatMap(_.asF[IO].void)
}
}
.use(_ => IO.println("Server started on port 8080") >> IO.never)
def runAsHttp4s: IO[Nothing] = {
val options =
addNotFoundHandler(Http4sServerOptions.customiseInterceptors[IO])
.options
EmberServerBuilder
.default[IO]
.withHttpApp(Http4sServerInterpreter[IO](options).toRoutes(endpoints).orNotFound)
.withPort(Port.fromInt(8080).get)
.build
.use(_ => IO.println("Server started on port 8080") >> IO.never)
}
override def run(args: List[String]): IO[ExitCode] = runAsVertx // runAsHttp4s
}
First run with runAsVertx, second run with runAsHttp4s. Then call:
curl http://localhost:8080/something
- With
runAsVertx, I got 404 response (default vertx response, but I expects 200 withCustom Not Found Response):<html><body><h1>Resource not found</h1></body></html> - With
runAsHttp4s, I got 200 response (as expected):Custom Not Found Response
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the VertxCatsServerInterpreter and VertxCatsServerOptions.customiseInterceptors usage in the reproduction, then compare it with Http4sServerInterpreter and Http4sServerOptions. Run the provided application with runAsVertx and curl /something, and verify that the Vertx server uses the configured reject handler and returns the expected 200 response.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100