Skip to content

Instantly share code, notes, and snippets.

@dacr
Created January 28, 2024 10:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dacr/c65ac91351115c2c1000215938d24774 to your computer and use it in GitHub Desktop.
Save dacr/c65ac91351115c2c1000215938d24774 to your computer and use it in GitHub Desktop.
http server random hello world using sealed traits or union types - experiments / published by https://github.com/dacr/code-examples-manager #5a1b725d-853a-45c6-9d9d-612f67174552/2a47363adfab9cd11620c72118d3518bd40a11ee
// summary : http server random hello world using sealed traits or union types - experiments
// keywords : scala, zio, tapir, http, zhttp, @testable, @exclusive
// publish : gist
// authors : David Crosson
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2)
// id : 5a1b725d-853a-45c6-9d9d-612f67174552
// created-on : 2024-01-24T09:46:26+01:00
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file
// test-with : curl -L http://127.0.0.1:8080/hello
// ---------------------
//> using scala "3.3.1"
//> using dep "com.softwaremill.sttp.tapir::tapir-zio:1.9.6"
//> using dep "com.softwaremill.sttp.tapir::tapir-json-zio:1.9.6"
//> using dep "com.softwaremill.sttp.tapir::tapir-json-pickler:1.9.6"
//> using dep "com.softwaremill.sttp.tapir::tapir-zio-http-server:1.9.6"
//> using dep "com.softwaremill.sttp.tapir::tapir-swagger-ui-bundle:1.9.6"
// ---------------------
import zio.*
import zio.http.Server
//import zio.json.{JsonCodec, jsonDiscriminator}
//import sttp.tapir.json.zio.*
import sttp.tapir.json.pickler.*
import sttp.tapir.Codec.JsonCodec
import sttp.tapir.ztapir.*
import sttp.tapir.server.ziohttp.ZioHttpInterpreter
import sttp.apispec.openapi.Info
import sttp.tapir.generic.Configuration
import sttp.tapir.swagger.bundle.SwaggerInterpreter
import sttp.tapir.generic.auto.*
/*
curl -L http://127.0.0.1:8080/docs
*/
object WebApp extends ZIOAppDefault {
// -------------------------------------------------------------------------
sealed trait Feedback
case class Message(userText: String) extends Feedback
sealed trait Greetings
case class Simple(message: Message) extends Greetings
case class Polite(bodyTile: Int, message: Message) extends Greetings
// -------------------------------------------------------------------------
implicit val tapirConfig: Configuration =
Configuration.default
.withDiscriminator("@kind")
.withKebabCaseMemberNames
.withKebabCaseDiscriminatorValues
implicit lazy val feedbackRW: upickle.default.ReadWriter[Feedback] = upickle.default.macroRW
implicit lazy val messageRW: upickle.default.ReadWriter[Message] = upickle.default.macroRW
implicit lazy val greetingsRW: upickle.default.ReadWriter[Greetings] = upickle.default.macroRW
implicit lazy val simpleRW: upickle.default.ReadWriter[Simple] = upickle.default.macroRW
implicit lazy val politeRW: upickle.default.ReadWriter[Polite] = upickle.default.macroRW
implicit lazy val feedbackPickler: Pickler[Feedback] = Pickler.derived
implicit lazy val feedbackCodec: JsonCodec[Feedback] = feedbackPickler.toCodec
implicit lazy val messagePickler: Pickler[Message] = Pickler.derived
implicit lazy val messageCodec: JsonCodec[Message] = messagePickler.toCodec
implicit lazy val greetingsPickler: Pickler[Greetings] = Pickler.derived
implicit lazy val greetingsCodec: JsonCodec[Greetings] = greetingsPickler.toCodec
implicit lazy val simplePickler: Pickler[Simple] = Pickler.derived
implicit lazy val simpleCodec: JsonCodec[Simple] = simplePickler.toCodec
implicit lazy val politePickler: Pickler[Polite] = Pickler.derived
implicit lazy val politeCodec: JsonCodec[Polite] = politePickler.toCodec
val helloEndPoint =
endpoint
.description("say hello")
.get
.in("hello")
.out(jsonBody[Feedback])
val helloRoute = helloEndPoint.zServerLogic[Any](_ => ZIO.succeed(Message("Hello")))
// --------------------------------------------------
val greetingEndPoint =
endpoint
.description("Return random greeting")
.get
.in("greeting")
.out(jsonBody[Greetings])
val greetings = List[Greetings](
Simple(Message("Hi")),
Simple(Message("Hello")),
Polite(30, Message("Nice to meed you"))
)
val greetingRoute = greetingEndPoint.zServerLogic[Any](_ => Random.shuffle(greetings).map(_.head))
// --------------------------------------------------
val docEndpoints =
SwaggerInterpreter()
.fromServerEndpoints(
List(helloRoute, greetingRoute),
Info(title = "Greeting API", version = "1.0", description = Some("Everything required to be polite"))
)
// --------------------------------------------------
val routes = ZioHttpInterpreter().toHttp(List(helloRoute, greetingRoute) ++ docEndpoints)
// --------------------------------------------------
override def run =
Server
.serve(routes)
.provide(Server.default)
}
WebApp.main(Array.empty)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment