Last active
May 25, 2024 08:38
-
-
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/7944c5966360c2ce1072e1e6207f378bd913a750
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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.4.2" | |
//> 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