### Install Zio Tapir Laminar Library (SBT) Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/getting-started.md This snippet shows how to add the Zio Tapir Laminar library as a dependency in your Scala project using SBT. Ensure you use the correct version that matches your sttp client version. ```sbt // ScalaJs libraryDependencies += "dev.cheleb" %%% "zio-tapir-laminar" % "{{ projectVersion}}" ``` -------------------------------- ### Create Tapir Endpoint with Zio and Laminar (Scala) Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/getting-started.md This Scala code demonstrates how to define a Tapir GET endpoint that accepts no input, returns a JSON response of type `GetResponse`, and handles errors. It utilizes Zio for effect management and Laminar's EventBus for emitting responses. ```scala import zio.* import zio.json.* import sttp.tapir.* import dev.cheleb.ziotapir.laminar.* // From a classical tapir: // // With a response type `GetResponse` case class GetResponse( args: Map[String, String], headers: Map[String, String] ) derives JsonCodec // Create an endpoint that handles a GET request val get = endpoint.get .in("get") .out(jsonBody[GetResponse]) .errorOut(statusCode and plainBody[String]) .mapErrorOut[Throwable](HttpError.decode)(HttpError.encode) // Create an event bus for the response type val eventBus = EventBus[GetResponse]() // Use the endpoint as as ZIO effect get(()) .emit(eventBus) ``` -------------------------------- ### Full-Stack Scala.js App with ZIO, Laminar, Tapir Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt This comprehensive example showcases a complete frontend application built with ZIO, Laminar, and Tapir in Scala.js. It defines multiple endpoints for GET requests and streaming JSONL data. The application includes buttons to trigger API calls, display results, and handle streaming updates reactively using EventBus and Laminar's reactive primitives. Dependencies include zio.*, zio.json.*, com.raquo.laminar.api.L.*, dev.cheleb.ziotapir.laminar.*, org.scalajs.dom, and sttp.model.Uri. ```scala import zio.* import zio.json.* import com.raquo.laminar.api.L.* import dev.cheleb.ziotapir.laminar.* import org.scalajs.dom import sttp.model.Uri // Define endpoints val getEndpoint: Endpoint[Unit, Unit, Throwable, GetResponse, Any] = endpoint.get.in("get").out(jsonBody[GetResponse]) val streamEndpoint: Endpoint[Unit, Unit, Throwable, Stream[Throwable, Byte], ZioStreams] = endpoint.get.in("data.jsonl").out(streamBody(ZioStreams)(...)) // Setup val httpbin = Uri.unsafeParse("https://httpbin.org") val resultBus = EventBus[String]() // Application val myApp = div( h1("ZIO Laminar Tapir Demo"), // Simple API call button( "Fetch Data", onClick --> (_ => getEndpoint(()).run(httpbin)) ), // API call with event emission button( "Fetch and Display", onClick --> (_ => getEndpoint(()).emit(httpbin, new EventBus[GetResponse]().map(_.toJsonPretty) )) ), // Streaming JSONL button( "Stream Data", onClick --> (_ => streamEndpoint(()).jsonlEither[Organisation] { result => resultBus.emit(result.toJsonPretty) } ) ), // Display results div( h3("Results:"), child <-- resultBus.events .scanLeft("")((acc, next) => acc + "\n" + next) .map(text => pre(text)) ) ) @main def main = val containerNode = dom.document.getElementById("app") render(containerNode, myApp) ``` -------------------------------- ### Server-Side Controller (Backend) Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Defines server-side endpoints with automatic route registration and error handling. This example shows an unsecured controller for fetching data. ```APIDOC ## Unsecured Controller ### Description Provides an unsecured endpoint for fetching data, including arguments and headers. ### Method GET ### Endpoint /api/data ### Parameters #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **GetResponse** - An object containing arguments and headers. - **args** (Map[String, String]) - Key-value pairs of arguments. - **headers** (Map[String, String]) - Key-value pairs of headers. #### Response Example ```json { "args": { "key": "value" }, "headers": { "content-type": "application/json" } } ``` ``` -------------------------------- ### Local Storage Integration Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Persist and retrieve typed data from browser localStorage with automatic JSON serialization. Covers setting, getting, removing, and clearing storage. ```APIDOC ## Local Storage Integration ### Description Provides utilities for interacting with browser localStorage, enabling typed data persistence and retrieval using JSON serialization. ### Methods - **Storage.set(key: String, value: T)**: Saves a value to localStorage. - **Storage.get[T](key: String)**: Retrieves and deserializes a value from localStorage. - **Storage.remove(key: String)**: Removes a specific key-value pair from localStorage. - **Storage.removeAll()**: Clears all data from localStorage. ### Parameters - **key** (String) - The key for the localStorage item. - **value** (T) - The value to be stored (must be JSON serializable). ### Request Example ```scala import dev.cheleb.ziotapir.Storage import zio.json._ case class UserPreferences(theme: String, language: String) derives JsonCodec val prefs = UserPreferences("dark", "en") Storage.set("user-prefs", prefs) val loadedPrefs: Option[UserPreferences] = Storage.get[UserPreferences]("user-prefs") loadedPrefs match { case Some(preferences) => console.log(s"Theme: ${preferences.theme}") case None => console.log("No preferences found") } Storage.remove("user-prefs") Storage.removeAll() ``` ### Response #### Success Response - **Storage.set**: Returns Unit. - **Storage.get[T]**: Returns Option[T]. - **Storage.remove**: Returns Unit. - **Storage.removeAll**: Returns Unit. #### Response Example ```json { "theme": "dark", "language": "en" } ``` ``` -------------------------------- ### Route Aggregation Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Combine routes from multiple controllers into a single server configuration. This example shows how to gather both standard and streaming routes. ```APIDOC ## Route Aggregation ### Description Aggregates server endpoints from multiple controllers, separating standard routes from streaming routes. ### Method N/A (Configuration) ### Endpoint N/A (Aggregated endpoints) ### Parameters None ### Request Example None ### Response #### Success Response (N/A) - **List[ServerEndpoint[Any, Task]]** - A list of all standard server endpoints. - **List[ServerEndpoint[ZioStreams, Task]]** - A list of all streaming server endpoints. #### Response Example None ``` -------------------------------- ### Import ZIO Laminar Tapir Extensions Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/usage.md This snippet shows the primary import statement required to use the ZIO Laminar Tapir library. It grants access to core functionalities for integrating Tapir endpoints with ZIO effects and Laminar event buses. ```scala import dev.cheleb.ziotapir.laminar.* ``` -------------------------------- ### Build ZIO Effect from Tapir Endpoint (Scala) Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/usage.md Demonstrates how to convert a Tapir endpoint definition into a ZIO effect. The resulting effect takes the endpoint's required input and produces a ZIO computation that can be run within a specified environment, such as `BackendClient`. ```scala val getEndpoint: Endpoint[Unit, Int, Throwable, GetResponse, Any] = ??? val getIO = getEndpoint(1) val getIO: RIO[BackendClient, GetResponse] = getEndpoint(1) ``` -------------------------------- ### Secured Server-Side Controller with Authentication in Scala Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Implements a secured server-side controller that requires authentication using bearer tokens. It extracts user principals from JWT tokens and performs authorization checks. This controller exposes a '/api/protected' GET endpoint accessible only to users with the 'admin' role. Dependencies include ZIO and Tapir. ```scala import dev.cheleb.ziotapir.* import sttp.tapir.* import sttp.tapir.ztapir.* import zio.* case class UserPrincipal(userId: String, roles: Set[String]) class SecuredController extends SecuredBaseController[String, UserPrincipal]( token => // Extract principal from JWT token ZIO.attempt { val decoded = decodeJWT(token) // Your JWT decode logic UserPrincipal(decoded.userId, decoded.roles) } ) { private val protectedEndpoint = endpoint .securityIn(auth.bearer[String]()) .get .in("api" / "protected") .out(jsonBody[SecretData]) override def routes = List( protectedEndpoint.zServerAuthenticatedLogic { principal => _ => if (principal.roles.contains("admin")) { ZIO.succeed(SecretData("Top secret information")) } else { ZIO.fail(new RuntimeException("Unauthorized")) } } ) } ``` -------------------------------- ### Local Storage Integration with JSON Serialization in Scala Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Provides utilities for interacting with browser localStorage, enabling persistence and retrieval of typed data. It automatically handles JSON serialization and deserialization using ZIO JSON. This snippet demonstrates setting, getting, removing, and clearing data. Dependencies include ZIO JSON. ```scala import dev.cheleb.ziotapir.Storage import zio.json.* case class UserPreferences(theme: String, language: String) derives JsonCodec // Save to localStorage val prefs = UserPreferences("dark", "en") Storage.set("user-prefs", prefs) // Retrieve from localStorage val loadedPrefs: Option[UserPreferences] = Storage.get[UserPreferences]("user-prefs") loadedPrefs match { case Some(preferences) => console.log(s"Theme: ${preferences.theme}") case None => console.log("No preferences found") } // Remove specific key Storage.remove("user-prefs") // Clear all storage Storage.removeAll() ``` -------------------------------- ### Unsecured Server-Side Controller in Scala Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Defines an unsecured server-side controller using ZIO Tapir. It automatically registers endpoints and handles errors. This controller exposes a '/api/data' GET endpoint that returns sample data. Dependencies include ZIO, Tapir, and ZIO JSON. ```scala import dev.cheleb.ziotapir.* import sttp.tapir.* import sttp.tapir.json.zio.* import sttp.tapir.ztapir.* import zio.* // Unsecured controller class DataController extends BaseController { private val baseEndpoint = endpoint .in("api" / "data") .errorOut(statusCode and plainBody[String]) .mapErrorOut[Throwable](HttpError.decode)(HttpError.encode) private val getDataEndpoint = baseEndpoint .get .out(jsonBody[GetResponse]) override def routes = List( getDataEndpoint.zServerLogic { _ => ZIO.succeed(GetResponse( args = Map("key" -> "value"), headers = Map("content-type" -> "application/json") )) } ) } ``` -------------------------------- ### Emit ZIO Effect Response to Laminar Event Bus (Scala) Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/usage.md Shows how to execute a ZIO effect built from a Tapir endpoint and emit its successful response to a Laminar event bus. If an error occurs during the effect's execution, it will be logged to the console. ```scala val _: Unit = getIO.emit(eventBus) ``` -------------------------------- ### Define a Secured Endpoint in Scala Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/advanced/secured.md This snippet shows how to define a secured GET endpoint using Tapir. It specifies that authentication is handled via a bearer token (JWT) and defines input query parameters and output JSON body. ```scala val securedEndpoint: Endpoint[String, Int, Throwable, GetResponse, Any] = endpoint.get .securityIn(auth.bearer[String]("token")) .in("secured") .in(query[Int]("id")) .out(jsonBody[GetResponse]) .errorOut(jsonBody[Throwable]) ``` -------------------------------- ### Handle HTTP Errors in Scala Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt This example demonstrates how to handle HTTP errors with custom error types and status codes in Scala. It defines an endpoint that maps output errors to a custom HttpError type and shows how to fail a server logic with this error. Client-side error handling involves listening to events on an error bus and pattern matching on the HttpError. Dependencies include dev.cheleb.ziotapir.HttpError and sttp.model.StatusCode. ```scala import dev.cheleb.ziotapir.HttpError import sttp.model.StatusCode val baseEndpoint = endpoint .errorOut(statusCode and plainBody[String]) .mapErrorOut[Throwable](HttpError.decode)(HttpError.encode) // Custom error handling in server logic getEndpoint.zServerLogic { _ => ZIO.fail(HttpError( StatusCode.NotFound, "Resource not found", new RuntimeException("Not found") )) } // Client-side error handling getEndpoint(()).run(errorBus) // Errors emitted to errorBus errorBus.events.foreach { error => error match { case HttpError(status, msg, _) => console.log(s"HTTP $status: $msg") case other => console.log(s"Error: ${other.getMessage}") } } ``` -------------------------------- ### Emit ZIO Effect Response or Error to Laminar Event Buses (Scala) Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/usage.md Illustrates how to run a ZIO effect and emit either the successful response to one event bus or any error that occurs to a separate error event bus. This provides distinct handling for success and failure scenarios. ```scala val _: Unit = getIO.emit(eventBus, errorBus) ``` -------------------------------- ### Configure Backend URLs in Scala Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt This snippet shows how to configure backend URLs for different environments using BackendClientLive. It supports automatic detection of localhost for development and the origin URL for production. You can also define custom backend configurations and create specific API URLs with path segments. Dependencies include dev.cheleb.ziotapir.BackendClientLive and sttp.model.Uri. ```scala import dev.cheleb.ziotapir.BackendClientLive import sttp.model.Uri // Automatic URL detection (localhost in dev, origin in production) val baseUrl: Uri = BackendClientLive.backendBaseURL // Create URL with path segments val apiUrl: Uri = BackendClientLive.url("api", "v1", "users") // Custom backend configuration val customBackend = BackendClientLive.configuredLayerOn( Uri.unsafeParse("https://api.staging.example.com") ) // Development mode: set DEV_API_URL in JavaScript // DEV_API_URL = "http://localhost:9999/"; ``` -------------------------------- ### Session Management with Reactive Signals (Scala) Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Provides reactive signals for managing authentication state, allowing the UI to update automatically based on login status. It includes methods to load saved user state, conditionally render UI elements based on session activity, and clear user sessions. This integrates seamlessly with Laminar's reactive programming model. ```scala import dev.cheleb.ziotapir.laminar.* import com.raquo.laminar.api.L.* given session: Session[UserToken] = new SessionLive[UserToken]() // Load saved session on app start session.loadUserState() // Reactive UI based on session state val authView: Signal[HtmlElement] = session { // When not logged in div( button("Login", onClick --> loginHandler) ) } { // When logged in userToken => div( span(s"Welcome ${userToken.userId}"), button("Logout", onClick --> (_ => session.clearUserState())) ) } // Render reactive view val app = div( h1("My App"), child <-- authView ) // Conditional execution when active val conditionalView: Signal[Option[HtmlElement]] = session.whenActive { div("User is logged in") } ``` -------------------------------- ### Route Aggregation for Server Endpoints in Scala Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Demonstrates how to aggregate server endpoints from multiple controllers into a single server configuration. It uses `gatherRoutes` to collect both standard and streaming routes from a list of controllers. Dependencies include ZIO Tapir and ZIO. ```scala import dev.cheleb.ziotapir.* import sttp.tapir.server.ServerEndpoint import zio.Task object ApiServer extends Routes { val controllers = List( new DataController(), new SecuredController(), new StreamController() ) // Gather all standard routes val allRoutes: List[ServerEndpoint[Any, Task]] = gatherRoutes(_.routes)(controllers) // Gather all streaming routes val streamRoutes: List[ServerEndpoint[ZioStreams, Task]] = gatherRoutes(_.streamRoutes)(controllers) } ``` -------------------------------- ### Configure Development Backend URL in JavaScript Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/advanced/origin.md Sets the backend API URL for a frontend application in development mode. This JavaScript variable is used by Vite to proxy requests to the specified backend service. ```javascript DEV_API_URL = "http://aserver.com" ``` -------------------------------- ### Handle Streaming Responses with JSONL Parsing in Scala Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Defines and processes streaming endpoints that automatically parse JSON Lines (JSONL) formatted data. It supports direct processing, error handling with Either, state accumulation using foldZIO, and streaming from remote URIs. Dependencies include ZIO, Tapir, and ZIO JSON. ```scala import dev.cheleb.ziotapir.laminar.* import sttp.tapir.* import sttp.capabilities.zio.ZioStreams import zio.stream.* import zio.json.* // Define streaming endpoint val streamEndpoint: Endpoint[Unit, Unit, Throwable, Stream[Throwable, Byte], ZioStreams] = endpoint .get .in("api" / "stream") .out(streamBody(ZioStreams)( summon[Schema[Organisation]], CodecFormat.TextEventStream() )) case class Organisation(id: UUID, name: String, location: Option[LatLon]) derives JsonCodec // Process each item in stream streamEndpoint(()).jsonl[Organisation] { org => console.log(s"Received: ${org.name}") } // Process with Either for error handling streamEndpoint(()).jsonlEither[Organisation] { case Right(org) => console.log(s"Success: ${org.name}") case Left(error) => console.log(s"Parse error: $error") } // Fold over stream with state accumulation val initialState: List[Organisation] = List.empty streamEndpoint(()).jsonlFoldZIO(initialState) { (acc, org) => ZIO.succeed(org :: acc) } // Stream from different origin val remoteUri = Uri.unsafeParse("https://data.example.com") streamEndpoint(()).jsonl[Organisation](remoteUri) { org => console.log(org.name) } ``` -------------------------------- ### Usage Pattern: ZIO Effect from Tapir Endpoint - Scala Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/README.md This code snippet demonstrates the typical usage pattern for integrating Tapir endpoints with ZIO effects in a Laminar application. It shows how to construct a ZIO effect from a Tapir endpoint definition and then how to execute this effect, emitting the response to a specified event bus. ```scala import dev.cheleb.ziotapir.laminar.* // 1. Build ZIO effect from Tapir endpoint val effect = AnEndpoints.get(1) // 2. Run effect and emit response to event bus effect.emit(eventBus) ``` -------------------------------- ### Streaming Endpoint with JSONL Parsing Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt This section details how to handle streaming responses with automatic JSON Lines parsing. It covers processing individual items, handling errors with Either, folding over the stream with state, and streaming from remote origins. ```APIDOC ## GET /api/stream ### Description Handles streaming responses with automatic JSON Lines parsing and processing. ### Method GET ### Endpoint /api/stream ### Parameters #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **Stream[Throwable, Organisation]** - A stream of Organisation objects parsed from JSON Lines. #### Response Example ```json { "id": "a1b2c3d4-e5f6-7890-1234-567890abcdef", "name": "Example Corp", "location": { "latitude": 40.7128, "longitude": -74.0060 } } ``` ``` -------------------------------- ### Secured Server-Side Controller Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Implement authenticated endpoints with principal extraction and authorization logic. This controller uses JWT for authentication. ```APIDOC ## Secured Controller ### Description Provides a secured endpoint that requires authentication via a bearer token and authorization based on user roles. ### Method GET ### Endpoint /api/protected ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Headers - **Authorization** (string) - Required - Bearer token for authentication. ### Response #### Success Response (200) - **SecretData** - An object containing secret information. - **secret** (string) - The secret data. #### Error Response (401/403) - **String** - Unauthorized or insufficient privileges. #### Response Example ```json { "secret": "Top secret information" } ``` ``` -------------------------------- ### Build ZIO Effect from Tapir Endpoint and Emit to Event Bus Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/index.md This snippet demonstrates how to create a ZIO effect from a Tapir endpoint definition and then run that effect to emit the response to an event bus. It handles request/response marshalling, JWT tokens, and client management. ```Scala import dev.cheleb.ziotapir.laminar.* AnEndpoints .get(1) // (1) Build an ZIO effect from a tapir endpoint .emit(eventBus) // (2) Run the effect and emit the response to an event bus ``` -------------------------------- ### Convert Tapir Endpoint to ZIO Effect (Scala) Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Converts a Tapir endpoint definition into a ZIO effect that can be executed within a frontend application. This method requires a BackendClient for communication and handles potential Throwables. It simplifies making HTTP requests by abstracting away the underlying client implementation. ```scala import dev.cheleb.ziotapir.laminar.* import sttp.tapir.* import sttp.tapir.json.zio.* import zio.json.* import com.raquo.laminar.api.L.* // Define response type case class GetResponse(args: Map[String, String], headers: Map[String, String]) derives JsonCodec // Define endpoint val getEndpoint: Endpoint[Unit, Unit, Throwable, GetResponse, Any] = endpoint .get .in("api" / "data") .out(jsonBody[GetResponse]) // Convert endpoint to ZIO and execute val effect = getEndpoint(()) // Returns ZIO[BackendClient, Throwable, GetResponse] effect.run // Execute the effect, prints errors to console ``` -------------------------------- ### Convert Tapir Endpoint to ZIO Effect - Scala Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/README.md The `BackendClient` trait facilitates the conversion of Tapir HTTP API endpoints into ZIO `Task` effects. This allows for executing API requests within the ZIO ecosystem, handling potential errors as `Throwable` and returning the successful result `O`. It takes an endpoint definition and a payload as input. ```scala def requestZIO[I, E <: Throwable, O]( endpoint: Endpoint[Unit, I, E, O, Any] )(payload: I): Task[O] ``` -------------------------------- ### Reactive Session State with Laminar Signals - Scala Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/README.md The `Session` trait from Laminar provides a mechanism for managing reactive authentication state. It allows components to react to changes in the session, offering different content based on whether a user session is active (`withSession`) or not (`withoutSession`). This is managed through Laminar's `Signal`. ```scala def apply[A](withoutSession: => A)( withSession: UserToken => A ): Signal[A] ``` -------------------------------- ### Define Streaming Endpoint with Tapir and ZIO Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/advanced/streaming.md Defines a streaming endpoint using Tapir and ZIO Streams. This Scala code snippet illustrates how to create an endpoint that outputs a stream of data, specified with a schema and content type. ```scala val allStream : Endpoint[Unit, Unit, Throwable, Stream[Throwable, Byte], ZioStreams] = baseEndpoint .tag("Admin") .name("organisation stream") .get .in("api" / "organisation" / "stream") .out( streamBody(ZioStreams)( summon[Schema[Organisation]], CodecFormat.TextEventStream() ) ) .description("Get all organisations") ``` -------------------------------- ### Stream and Process JSON Lines Data with ZIO Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/advanced/streaming.md Demonstrates how to consume a streaming endpoint and process incoming data formatted as JSON Lines (jsonl) using ZIO. The `jsonl` method deserializes each line as a specified type and applies a provided sink function. ```scala HttpBinEndpoints.allStream(()) .jsonl[Organisation](localhost, organisation => Console.printLine(organisation)) ``` -------------------------------- ### Call Secured Tapir Endpoint with JWT (Scala) Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt Enables calling authenticated Tapir endpoints by automatically injecting JWT tokens obtained from session management. This requires defining a token type that extends `WithToken` and ensuring an implicit `Session` instance is available. The token is automatically retrieved and added to the request headers. ```scala import dev.cheleb.ziotapir.laminar.* import dev.cheleb.ziojwt.WithToken import zio.json.* // Define user token type case class UserToken(token: String, expiration: Long, userId: String) extends WithToken derives JsonCodec // Create session manager (implicit) given session: Session[UserToken] = new SessionLive[UserToken]() // Define secured endpoint val securedEndpoint: Endpoint[String, Unit, Throwable, GetResponse, Any] = endpoint .securityIn(auth.bearer[String]()) .get .in("api" / "protected") .out(jsonBody[GetResponse]) // Call secured endpoint - token automatically injected from session securedEndpoint(()).emit(eventBus) // Save token to session after login val loginResponse = UserToken("jwt.token.here", 1735689600L, "user123") session.saveToken(loginResponse) // Check if session is active if (session.isActive) { securedEndpoint(()).run } // Logout session.clearUserState() ``` -------------------------------- ### Tapir Endpoint Emission with Base URI in Scala Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/advanced/origin.md Demonstrates how to emit a Tapir endpoint request using a base URI in Scala. This is useful when the frontend is served from a different origin than the backend, particularly in production mode. ```scala val httpbin = Uri.unsafeParse("https://httpbin.org") HttpBinEndpoints.get(()) .emit(httpbin, eventBus) ``` -------------------------------- ### Provide JWT Session Context in Scala Source: https://github.com/cheleb/zio-laminar-tapir/blob/master/docs/_docs/advanced/secured.md This snippet demonstrates how to provide the necessary session context for JWT authentication in a Scala frontend application. The `given Session = MySession[MyToken]` line ensures that the ZIO Laminar Tapir library can manage JWT tokens for secured endpoints. ```scala given Session = MySession[MyToken] ``` -------------------------------- ### Emit Tapir Endpoint Results to Laminar EventBus (Scala) Source: https://context7.com/cheleb/zio-laminar-tapir/llms.txt This functionality allows the results of a Tapir endpoint call to be emitted directly to Laminar's EventBus for reactive UI updates. It supports emitting success responses to one bus and errors to another, or emitting an Either[Error, Success] to a single bus. You can also specify a custom origin URI for the request. ```scala import dev.cheleb.ziotapir.laminar.* import com.raquo.laminar.api.L.* import sttp.model.Uri val eventBus = new EventBus[GetResponse]() val errorBus = new EventBus[Throwable]() // Emit success to eventBus and errors to errorBus getEndpoint(()).emit(eventBus, errorBus) // Emit to different origin val remoteUri = Uri.unsafeParse("https://api.example.com") getEndpoint(()).emit(remoteUri, eventBus, errorBus) // Emit Either[Error, Success] to single bus val eitherBus = new EventBus[Either[Throwable, GetResponse]]() getEndpoint(()).emitEither(eitherBus) // Use in Laminar component val myComponent = div( button( "Fetch Data", onClick --> (_ => getEndpoint(()).emit(eventBus)) ), child <-- eventBus.events.map(response => pre(response.toJsonPretty) ) ) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.