shortTitle | shortDescription | expandText | anchorTarget | icon |
---|---|---|---|---|
Server-side | High-throughput HTTP servers and clients. Safe, scalable, and principled concurrency. Reliable data validation with powerful transformations. | Creating Services | creating-services | icon5.svg |
Scala's expressivity and compiler-enforced safety makes it easier to construct reliable concurrent code.
With Scala, your programs take full advantage of multi-core and distributed architectures, ensure safe access to resources, and apply back-pressure to data producers according to your processing rate.
One popular open-source option for managing concurrency in Scala is Cats Effect, combined with http4s for defining servers and routing. Click below to see other solutions.
libraries for Concurrency and distribution// HTTP server routing definition val service = HttpRoutes.of: case GET -> Root / "weather" => // route '/weather' for winner <- fetch1.race(fetch2).timeout(10.seconds) response <- Ok(WeatherReport.from(winner)) yield response
def fetch1 = fetchWeather(server1) // expensive Network IO def fetch2 = fetchWeather(server2) // expensive Network IO
Use the best of Scala, or leverage libraries from the Java and JavaScript ecosystems.
Build with monolithic or microservice architectures. Retain resource-efficiency. Persist your data to any kind of database. Transform, validate, and serialize data into any format (JSON, protobuf, Parquet, etc.).
Whether you compile for the Node.js or Java platform, Scala's interop with both gives you access to even more widely-proven libraries.
Find the right library for your next Scala projectdef Device(lastTemp: Option[Double]): Behavior[Message] = Behaviors.receiveMessage: case RecordTemperature(id, value, replyTo) => replyTo ! TemperatureRecorded(id) Device(lastTemp = Some(value))
case ReadTemperature(id, replyTo) => replyTo ! RespondTemperature(id, lastTemp) Behaviors.same
Harness the “Code as Data” Paradigm: define once, use everywhere.
Scala's rich type system and metaprogramming facilities give the power to automatically derive helpful utilities from your code.
One such example library is Tapir, letting you use Scala as a declarative language to describe your HTTP endpoints. From this single source of truth, you can automatically derive their server implementation, their client implementation, and both human-readable and machine-readable documentation.
Because everything is derived from a type-safe definition, endpoint invocations are checked to be safe at compile-time, across the frontend and backend.
Read more in the Tapir docs// type-safe endpoint definition val reportEndpoint = endpoint .in("api" / "report" / path[String]("reportId")) .out(jsonBody[Report])
// derived Docs, Server and Client val apiDocs = docsReader .toOpenAPI(reportEndpoint, "Fetch Report", "1.0.0") val server = serverBuilder(port = "8080") .addEndpoint(reportEndpoint.handle(fetchReport)) .start() val client = clientReader .toRequest(reportEndpoint, "http://localhost:8080") val report: Future[Report] = client("5ca1a-78fc8d6") // call like any function