Skip to content

Instantly share code, notes, and snippets.

@dacr
Created June 15, 2024 07:58
Show Gist options
  • Save dacr/920ba4ff5c3f2a81a5471fd2497e943d to your computer and use it in GitHub Desktop.
Save dacr/920ba4ff5c3f2a81a5471fd2497e943d to your computer and use it in GitHub Desktop.
Simple server side event (SSE) using http4s library / published by https://github.com/dacr/code-examples-manager #012de94c-7bf8-4d06-a0ec-816cb1afb873/f113bdfc443073b9ab555b636a6b4d471727e28f
// summary : Simple server side event (SSE) using http4s library
// keywords : scala, http4s, cats, http-server, tapir, sse, @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 : 012de94c-7bf8-4d06-a0ec-816cb1afb873
// created-on : 2024-06-13T15:28:17+02:00
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file
// test-with : curl http://127.0.0.1:8080/hi
// ---------------------
//> using scala "3.4.2"
//> using dep "com.softwaremill.sttp.tapir::tapir-zio:1.10.9"
//> using dep "com.softwaremill.sttp.tapir::tapir-http4s-server-zio:1.10.9"
//> using dep "com.softwaremill.sttp.tapir::tapir-json-zio:1.10.9"
//> using dep "com.softwaremill.sttp.tapir::tapir-swagger-ui-bundle:1.10.9"
//> using dep "com.softwaremill.sttp.tapir::tapir-openapi-docs:1.10.9"
//> using dep "org.http4s::http4s-blaze-server:0.23.16"
//> using dep "org.slf4j:slf4j-simple:2.0.13"
//> using options -Ykind-projector:underscores
// ---------------------
import cats.syntax.all.*
import org.http4s.{ServerSentEvent as _, *}
import org.http4s.blaze.server.BlazeServerBuilder
import org.http4s.server.Router
import org.http4s.implicits.*
import sttp.tapir.PublicEndpoint
import sttp.tapir.generic.auto.*
import sttp.tapir.swagger.bundle.SwaggerInterpreter
import sttp.tapir.server.http4s.ztapir.{ZHttp4sServerInterpreter, serverSentEventsBody}
import sttp.apispec.openapi.Info
import sttp.model.sse.ServerSentEvent
import sttp.tapir.ztapir.*
import zio.interop.catz.*
import zio.{Console, Task, UIO, ZIO, ZIOAppDefault}
import zio.durationInt
import zio.stream.*
object Hello extends ZIOAppDefault {
def hiLogic(givenName: Option[String]):UIO[Stream[Throwable, ServerSentEvent]] = ZIO.succeed {
ZStream
.from(List("Hi", "Hello", "Good morning", "How are you"))
.map(greeting => givenName.map(name => s"$greeting $name").getOrElse(greeting))
.forever
.map(greeting => ServerSentEvent(data=Some(greeting)))
.take(10)
}
val hiEndPoint =
endpoint
.description("Returns many greetings")
.get
.in("hi")
.in(query[Option[String]]("name").description("someone name"))
.out(serverSentEventsBody)
val hiEndPointWired = hiEndPoint.zServerLogic[Any](hiLogic)
val docEndPointWired =
SwaggerInterpreter()
.fromServerEndpoints(
List(hiEndPointWired),
Info(title = "Greeting API", version = "1.0", description = Some("Everything required to be polite"))
)
val routes: HttpRoutes[Task] = ZHttp4sServerInterpreter()
.from(hiEndPointWired :: docEndPointWired)
.toRoutes
def run = {
ZIO.executor.flatMap(executor =>
BlazeServerBuilder[Task]
.withExecutionContext(executor.asExecutionContext)
.bindLocal(8080)
.withHttpApp(Router("/" -> routes).orNotFound)
.serve
.compile
.drain
).timeout(60.seconds)
}
}
Hello.main(Array.empty)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment