Skip to content

Instantly share code, notes, and snippets.

View adamw's full-sized avatar

Adam Warski adamw

View GitHub Profile
object Server {
import Endpoints._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
// should fail with Error if user not found
def authorize(authToken: AuthToken): Future[Either[Error, User]] = ???
def findPetForUser(user: User, id: UUID): Future[Either[Error, Option[Pet]]] = ???
def addPetToUser(user: User, pet: Pet): Future[Either[Error, Unit]] = ???
import java.util.UUID
import io.circe.generic.auto._
import sttp.model.StatusCode
import sttp.tapir._
import sttp.tapir.json.circe._
object Endpoints {
case class AuthToken(token: String)
case class Error(msg: String, statusCode: StatusCode) extends Exception
case class User(id: UUID, name: String)
// the endpoints are interpreted as an http4s.HttpRoutes[IO]
import sttp.tapir.server.http4s._
import org.http4s.HttpRoutes
implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global
implicit val contextShift: ContextShift[IO] = IO.contextShift(ec)
implicit val timer: Timer[IO] = IO.timer(ec)
val routes: HttpRoutes[IO] = List(getPetWithLogic, addPetWithLogic).toRoutes
// expose routes using http4s
val getPetWithLogic =
secureEndpoint
.get
.in(query[UUID]("id").description("The id of the pet to find"))
.out(jsonBody[Pet])
.description("Finds a pet by id")
.serverLogic {
case (user, id) =>
findPetForUser(user, id).map {
case Right(Some(pet)) => Right(pet)
import sttp.tapir.json.circe._
import io.circe.generic.auto._
import sttp.tapir.server.PartialServerEndpoint
val error: EndpointOutput[Error] = stringBody.and(statusCode).mapTo(Error)
val secureEndpoint: PartialServerEndpoint[User, Unit, Error, Unit, Nothing, IO] =
endpoint
.in(auth.bearer[String].mapTo(AuthToken))
.in("api" / "1.0")
.errorOut(error)
import java.util.UUID
import cats.effect.{ContextShift, IO, Timer}
import sttp.tapir._
import sttp.model.StatusCode
case class AuthToken(token: String)
case class Error(msg: String, statusCode: StatusCode)
case class User(id: UUID, name: String)
case class Pet(id: UUID, kind: String, name: String)
// the endpoints are now interpreted as an akka.http.scaladsl.Route
import akka.http.scaladsl.server.Route
import sttp.tapir.server.akkahttp._
val routes: Route = List(getPetWithLogic, addPetWithLogic).toRoute
// expose routes using akka-http
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
// should fail with Error if user not found
def authorize(authToken: AuthToken): Future[User] = ???
def findPetForUser(user: User, id: UUID): Future[Option[Pet]] = ???
def addPetToUser(user: User, pet: Pet): Future[Unit] = ???
val getPetWithLogic = getPet.serverLogicRecoverErrors {
case (authToken, id) =>
case class User(id: UUID, name: String)
case class Pet(id: UUID, kind: String, name: String)
val getPet: Endpoint[(AuthToken, UUID), Error, Pet, Nothing] =
baseEndpoint
.get
.in(query[UUID]("id").description("The id of the pet to find"))
.out(jsonBody[Pet])
.description("Finds a pet by id")
import java.util.UUID
import sttp.tapir._
import sttp.tapir.json.circe._
import io.circe.generic.auto._
import sttp.model.StatusCode
case class AuthToken(token: String)
case class Error(msg: String, statusCode: StatusCode) extends Exception