Envelope threaded through the middleware pipeline for a single procedure
invocation. Middleware receive and return a %Resolution{}.
Field ownership
One struct holds everything. Each field has its own writer. Ownership
mirrors Plug.Conn:
:ctx— the transport sets it at construction. Middleware updates it withput_ctx/3orassign/3. Read by handlers.:private— middleware-owned. Useput_private/3for framework-internal scratch data. Handlers never see it, because they receive only:ctx.:params— reserved for middleware. The framework does not read or write it; validated input goes straight to the handler.:state— set to:haltedonly viahalt/2. Never set directly.:result— dispatcher-owned. Middleware should not write to it directly; usehalt/2to short-circuit with an error. Direct writes pre-dispatch are clobbered by the handler step.:procedure— set at construction time, never mutated.:resp_cookies— middleware-writable. Useput_resp_cookie/4ordelete_resp_cookie/3. The transport adapter drains this onto the response after dispatch. Format:%{name => {value, opts}}for set,%{name => {:delete, opts}}for delete.:resp_headers— middleware-writable. Useput_resp_header/3. The transport adapter appends these to the response. Duplicates are allowed (e.g. multipleSet-Cookievalues). Format:[{name, value}].:resp_session— middleware-writable. Useput_session/3,delete_session/2, orclear_session/1. The transport adapter drains this into the Plug session after dispatch. RequiresPlug.Sessionto be configured earlier in the pipeline. Keys must be atoms or strings, and Plug stores both as strings. Soput_session(res, :user_id, 1)reads back asctx.req.session["user_id"].:resp_session_clear— set only byclear_session/1. It wins over every other:resp_sessionentry.
All cookie, header, and session helpers are safe to call from middleware.
Halting
Calling halt/2 short-circuits remaining middleware and the handler. The
dispatcher returns the resolution unchanged from that point.
Summary
Types
Cookie entry in resp_cookies — either a set or delete instruction.
Session entry in resp_session — either a value to set or :delete.
Pipeline execution state.
Resolution envelope.
Functions
Stores application data under key in the context's :assigns map — the
primary way middleware passes request-scoped data to handlers.
Marks the entire session to be cleared on the response.
Marks a cookie for deletion on the response.
Marks a session key for deletion on the response.
Halts the pipeline with an error.
Replaces a known field on the nested %Context{} struct.
Stores framework/library-private request-scoped data under key in the
resolution's :private map. For application data, use assign/3 instead.
Stores a cookie to be set on the response.
Appends a response header. Duplicates are preserved (useful for headers like
set-cookie that must be set separately per cookie).
Stores a session key-value pair to be set on the response.
Types
Cookie entry in resp_cookies — either a set or delete instruction.
@type resp_session_entry() :: term() | :delete
Session entry in resp_session — either a value to set or :delete.
@type state() :: :continue | :halted
Pipeline execution state.
@type t() :: %RpcElixir.Resolution{ ctx: RpcElixir.Context.t(), params: map(), private: map(), procedure: String.t() | nil, resp_cookies: %{optional(String.t()) => resp_cookie_entry()}, resp_headers: [{String.t(), String.t()}], resp_session: %{optional(term()) => resp_session_entry()}, resp_session_clear: boolean(), result: {:ok, term()} | {:error, RpcElixir.RpcError.t()} | nil, state: state() }
Resolution envelope.
Functions
Stores application data under key in the context's :assigns map — the
primary way middleware passes request-scoped data to handlers.
Marks the entire session to be cleared on the response.
This sets the :resp_session_clear flag. The transport adapter then calls
Plug.Conn.clear_session/1. Any other resp_session entries are ignored
after a clear.
Marks a cookie for deletion on the response.
opts are forwarded to Plug.Conn.delete_resp_cookie/3 by the transport
adapter.
Marks a session key for deletion on the response.
@spec halt(t(), RpcElixir.RpcError.t() | term()) :: t()
Halts the pipeline with an error.
Accepts either a fully-formed %RpcError{} or any other term, which is
wrapped under code: :middleware_halted with the original term stored at
details.reason. After halting, downstream middleware and the handler are
skipped.
Replaces a known field on the nested %Context{} struct.
Raises KeyError if key is not a field on the context struct. To store
arbitrary request-scoped data, use assign/3 (application data) or
put_private/3 (framework/library data) instead.
Stores framework/library-private request-scoped data under key in the
resolution's :private map. For application data, use assign/3 instead.
Stores a cookie to be set on the response.
opts are forwarded directly to Plug.Conn.put_resp_cookie/4 by the
transport adapter. Supported options include :http_only, :secure,
:same_site, :max_age, :path, :domain, :sign, :encrypt.
Appends a response header. Duplicates are preserved (useful for headers like
set-cookie that must be set separately per cookie).
Stores a session key-value pair to be set on the response.
Requires Plug.Session to be configured in the Plug pipeline. The transport
adapter drains this into the session after dispatch.