Hello World Example
Simple Example
zio-http-example/src/main/scala/example/HelloWorld.scala
package example
import zio._
import zio.http._
object HelloWorld extends ZIOAppDefault {
// Responds with plain text
val homeRoute =
Method.GET / Root -> handler(Response.text("Hello World!"))
// Responds with JSON
val jsonRoute =
Method.GET / "json" -> handler(Response.json("""{"greetings": "Hello World!"}"""))
// Create HTTP route
val app = Routes(homeRoute, jsonRoute)
// Run it like any simple app
override val run = Server.serve(app).provide(Server.default)
}
Advanced Example
zio-http-example/src/main/scala/example/HelloWorldAdvanced.scala
package example
import scala.util.Try
import zio._
import zio.http._
import zio.http.netty.NettyConfig
import zio.http.netty.NettyConfig.LeakDetectionLevel
object HelloWorldAdvanced extends ZIOAppDefault {
// Set a port
val PORT = 58080
val fooBar =
Routes(
Method.GET / "foo" -> Handler.from(Response.text("bar")),
Method.GET / "bar" -> Handler.from(Response.text("foo")),
)
val app = Routes(
Method.GET / "random" -> handler(Random.nextString(10).map(Response.text(_))),
Method.GET / "utc" -> handler(Clock.currentDateTime.map(s => Response.text(s.toString))),
)
val run = ZIOAppArgs.getArgs.flatMap { args =>
// Configure thread count using CLI
val nThreads: Int = args.headOption.flatMap(x => Try(x.toInt).toOption).getOrElse(0)
val config = Server.Config.default
.port(PORT)
val nettyConfig = NettyConfig.default
.leakDetection(LeakDetectionLevel.PARANOID)
.maxThreads(nThreads)
val configLayer = ZLayer.succeed(config)
val nettyConfigLayer = ZLayer.succeed(nettyConfig)
(fooBar ++ app)
.serve[Any]
.provide(configLayer, nettyConfigLayer, Server.customized)
}
}
Advanced with CORS Example
zio-http-example/src/main/scala/example/HelloWorldWithCORS.scala
package example
import zio._
import zio.http.Header.{AccessControlAllowOrigin, Origin}
import zio.http.Middleware.{CorsConfig, cors}
import zio.http._
import zio.http.codec.PathCodec
import zio.http.template._
object HelloWorldWithCORS extends ZIOAppDefault {
val config: CorsConfig =
CorsConfig(
allowedOrigin = {
case origin if origin == Origin.parse("http://localhost:3000").toOption.get =>
Some(AccessControlAllowOrigin.Specific(origin))
case _ => None
},
)
val backend: Routes[Any, Response] =
Routes(
Method.GET / "json" -> handler(Response.json("""{"message": "Hello World!"}""")),
) @@ cors(config)
val frontend: Routes[Any, Response] =
Routes(
Method.GET / PathCodec.empty -> handler(
Response.html(
html(
p("Message: ", output()),
script("""
|// This runs on http://localhost:3000
|fetch("http://localhost:8080/json")
| .then((res) => res.json())
| .then((res) => document.querySelector("output").textContent = res.message);
|""".stripMargin),
),
),
),
)
val frontEndServer = Server.serve(frontend).provide(Server.defaultWithPort(3000))
val backendServer = Server.serve(backend).provide(Server.defaultWithPort(8080))
val run = frontEndServer.zipPar(backendServer)
}
Advanced with Middlewares Example
zio-http-example/src/main/scala/example/HelloWorldWithMiddlewares.scala
package example
import java.util.concurrent.TimeUnit
import zio._
import zio.http._
object HelloWorldWithMiddlewares extends ZIOAppDefault {
val routes: Routes[Any, Response] = Routes(
// this will return result instantly
Method.GET / "text" -> handler(ZIO.succeed(Response.text("Hello World!"))),
// this will return result after 5 seconds, so with 3 seconds timeout it will fail
Method.GET / "long-running" -> handler(ZIO.succeed(Response.text("Hello World!")).delay(5 seconds)),
)
val serverTime = Middleware.patchZIO(_ =>
for {
currentMilliseconds <- Clock.currentTime(TimeUnit.MILLISECONDS)
header = Response.Patch.addHeader("X-Time", currentMilliseconds.toString)
} yield header,
)
val middlewares =
// print debug info about request and response
Middleware.debug ++
// close connection if request takes more than 3 seconds
Middleware.timeout(3 seconds) ++
// add static header
Middleware.addHeader("X-Environment", "Dev") ++
// add dynamic header
serverTime
// Run it like any simple app
val run = Server.serve(routes @@ middlewares).provide(Server.default)
}