Running as a Play server
To expose endpoint as a play-server first add the following dependencies:
"com.softwaremill.sttp.tapir" %% "tapir-play-server" % "1.2.4"
and (if you don’t already depend on Play)
"com.typesafe.play" %% "play-akka-http-server" % "2.8.18"
or
"com.typesafe.play" %% "play-netty-server" % "2.8.18"
depending on whether you want to use netty or akka based http-server under the hood.
Then import the object:
import sttp.tapir.server.play.PlayServerInterpreter
The toRoutes
method requires a single, or a list of ServerEndpoint
s, which can be created by adding
server logic to an endpoint. For example:
import sttp.tapir._
import sttp.tapir.server.play.PlayServerInterpreter
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import akka.stream.Materializer
import play.api.routing.Router.Routes
implicit val materializer: Materializer = ???
def countCharacters(s: String): Future[Either[Unit, Int]] =
Future(Right[Unit, Int](s.length))
val countCharactersEndpoint: PublicEndpoint[String, Unit, Int, Any] =
endpoint.in(stringBody).out(plainBody[Int])
val countCharactersRoutes: Routes =
PlayServerInterpreter().toRoutes(countCharactersEndpoint.serverLogic(countCharacters _))
Bind the routes
Creating the HTTP server manually
An HTTP server can then be started as in the following example:
import play.core.server._
import play.api.routing.Router.Routes
val aRoute: Routes = ???
object Main {
// JVM entry point that starts the HTTP server
def main(args: Array[String]): Unit = {
val playConfig = ServerConfig(port =
sys.props.get("http.port").map(_.toInt).orElse(Some(9000))
)
NettyServer.fromRouterWithComponents(playConfig) { components =>
aRoute
}
}
}
As part of an existing Play application
Or, if you already have an existing Play application, you can create a Router
class and bind it to the application.
First, add a line like following in the routes
files:
-> /api api.ApiRouter
Then create a class like this:
class ApiRouter @Inject() () extends SimpleRouter {
override def routes: Routes = {
anotherRoutes.orElse(tapirGeneratedRoutes)
}
}
Find more details about how to bind a Router
to your application in the Play framework documentation.
Web sockets
The interpreter supports web sockets, with pipes of type Flow[REQ, RESP, Any]
. See web sockets
for more details.
The interpreter does not expose control frames (Ping
, Pong
and Close
), so any setting regarding them are discarded, however those that are emitted are sent to the client.
Configuration
The interpreter can be configured by providing a PlayServerOptions
value, see
server options for details.