-module(dream@context). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/dream/context.gleam"). -export([new_context/1]). -export_type([empty_context/0, app_context/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Request context for your application\n" "\n" " Context holds per-request data that changes with every request—user authentication,\n" " session info, request IDs, etc. It's passed to every middleware and controller.\n" "\n" " ## Empty Context\n" "\n" " For simple applications that don't need per-request context, Dream defaults to `EmptyContext`.\n" " You don't need to set it explicitly:\n" "\n" " ```gleam\n" " import dream/servers/mist/server.{listen, router}\n" " \n" " server.new()\n" " |> router(my_router)\n" " |> listen(3000)\n" " ```\n" "\n" " If you need to explicitly set EmptyContext (e.g., replacing a previously set context):\n" "\n" " ```gleam\n" " import dream/context.{type EmptyContext, EmptyContext}\n" " import dream/servers/mist/server.{context, listen, router}\n" " \n" " server.new()\n" " |> context(EmptyContext)\n" " |> router(my_router)\n" " |> listen(3000)\n" " ```\n" "\n" " ## App Context\n" "\n" " Dream also provides `AppContext` with a `request_id` field. Use this if you want\n" " basic request tracking but don't need custom context yet:\n" "\n" " ```gleam\n" " import dream/context.{type AppContext, AppContext}\n" " import dream/servers/mist/server.{context, listen, router}\n" " \n" " server.new()\n" " |> context(AppContext(request_id: \"\"))\n" " |> router(my_router)\n" " |> listen(3000)\n" " ```\n" "\n" " Most applications will eventually want their own custom context type.\n" "\n" " ## Custom Context\n" "\n" " Define your own context type to hold whatever per-request data you need:\n" "\n" " ```gleam\n" " import gleam/option.{None}\n" " \n" " pub type MyContext {\n" " MyContext(\n" " request_id: String,\n" " user: option.Option(User),\n" " session: Session,\n" " permissions: List(String),\n" " )\n" " }\n" " ```\n" "\n" " Then pass it to your server:\n" "\n" " ```gleam\n" " import dream/servers/mist/server.{context, listen, router, services}\n" " \n" " server.new()\n" " |> context(MyContext(\n" " request_id: \"\",\n" " user: None,\n" " session: empty_session(),\n" " permissions: [],\n" " ))\n" " |> services(my_services)\n" " |> router(my_router)\n" " |> listen(3000)\n" " ```\n" "\n" " ## Enriching Context in Middleware\n" "\n" " Middleware can update the context as requests flow through:\n" "\n" " ```gleam\n" " import dream/http/request.{type Request}\n" " import dream/http/response.{type Response, text_response}\n" " import dream/http/status.{unauthorized}\n" " import gleam/option.{Some}\n" " \n" " pub fn auth_middleware(\n" " request: Request,\n" " context: MyContext,\n" " services: Services,\n" " next: fn(Request, MyContext, Services) -> Response,\n" " ) -> Response {\n" " case extract_token(request) {\n" " Ok(token) -> {\n" " let user = verify_token(services.db, token)\n" " let new_context = MyContext(..context, user: Some(user))\n" " next(request, new_context, services)\n" " }\n" " Error(_) -> text_response(unauthorized, \"Authentication required\")\n" " }\n" " }\n" " ```\n" "\n" " The type system ensures your controllers receive the right context type.\n" ). -type empty_context() :: empty_context. -type app_context() :: {app_context, binary()}. -file("src/dream/context.gleam", 132). ?DOC( " Create a new AppContext\n" "\n" " Helper for creating the default context. If you're using a custom context,\n" " you'll create it directly without this function.\n" ). -spec new_context(binary()) -> app_context(). new_context(Request_id) -> {app_context, Request_id}.