Current section
Files
Jump to
Current section
Files
src/dream@context.erl
-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}.