Effects
The AST is the contract. ZIO[R, E, A] is the body.
Ris the environment. The example's writes needJwtClaim. Reads needAny.Eis the domain error..outError[NotFound](Status.NotFound)maps it for HTTP. MCP seesisError. Do not leak SQL or JWT library types intoE.Ais the success valueSchemaalready described.
Handler is Request => ZIO[R, E, Response] when you are still on raw routes. Api.bind is
In => ZIO[R, E, Out] once the endpoint exists. Both are ordinary ZIO. There is no event-loop
rule. Accept, read, and write run on the JVM, on Node, and on Native.
GET /shows/1 arrives. Path codec captures id = 1.
Request.get("/shows/1")Walk a request
Click a step. Decode is not your code. The bind is. Encode is not your code. Interrupting the connection interrupts the fiber. Same widget as Bind the effect.
Middleware is still an effect
@@ applies middleware. a ++ b composes: the request hits b first (outer), then a.
requestId, cors, compress, debug, and the auth helpers live here. They are Routes => Routes,
not a parallel effect system.
{
val routes =
Routes(Method.GET / "x" -> Handler.text("ok")) @@ Middleware.requestId()
routes(Request.get("/x")).map { res =>
res.header("X-Request-Id").exists(_.nonEmpty)
}
}trueStreams are streams
Bodies on the wire are streams. Body.asString / asBytes are for in-memory bodies.
SSE is a ZStream of ServerSentEvent. Do not pretend a stream is a List. Interrupt the
client, the stream fiber stops.