Awesome
Enterprise <image style="max-height:1.2em" src="https://github.githubassets.com/images/icons/emoji/unicode/1f680.png"><image style="max-height:1.2em" src="https://github.githubassets.com/images/icons/emoji/unicode/1fa90.png">
Minimalist library for creating HTTP services, using algebraic effects and handlers.
- βοΈ π¬ π§ͺ Β π·πΉπΆπ»πΆπ»ππ·π¬ Β π§ WIP π§
- Uses Scala 3.
- Uses Turbolift as effect system.
- Adapts parts of design of preexisting purely-functional HTTP libraries (Http4s, ZIO-Http) for the new effect system.
Design
Services are defined as values of type:
type MyHttpService = Response !! (Request.Fx & IO)
Which should be read as: "Computation, that returns Response
and requests 2 effects: Request.Fx
and IO
".
Request.Fx
is an instance of Turbolift's Reader
effect, predefined in Enterprise.
Services can also request other effects than these 2. However, they must be handled (eliminated) by the user,
before submitting the service to server. Multiple handlers can be chained, using Turbolift's &&&!
operator.
Examples of such optional effects, predefined in Enterprise, are:
ErrorResponse.Fx
- An instance of Turbolift'sError
effect. Allows interruption of processing of the request, returning givenResponse
value.Router.Fx
- An instance of Turbolift'sChoice
effect. Allows defining routes by partial functions. Composition can be done with Turbolift's++!
operator (similar to<|>
ofAlternative
).
With future version of Turbolift, service will be able to use any number of effects that are handled outside the server scope.
Example
Run the server with scala-cli
:
//> using scala "3.3.1"
//> using dep "io.github.marcinzh::enterprise-core:0.2.0"
import turbolift.!!
import turbolift.Extensions._
import enterprise.{Response, Router}
import enterprise.server.{Server, Config}
import enterprise.DSL._
@main def main =
Server.serve:
Router:
case GET / "sarcastic" / text =>
val text2 = text.zipWithIndex.map((c, i) => if i % 2 == 0 then c.toLower else c.toUpper).mkString
Response.text(text2).pure_!!
.handleWith:
Router.handler
.handleWith:
Server.undertow &&&!
Config.localhost(9000).toHandler
.unsafeRunST
Query the server with httpie
:
http GET http://localhost:9000/sarcastic/assimilate
See examples folder for more.