Expand description
Runtime primitives for the transport rpc generation style.
See docs/design/rpc-transport.md for the full design. This module
provides the binding-side surface that schemas with transport rpc
generate against:
POST /rpc/{op_id}— unary calls. Body is the codec-encoded input (no frame wrapper); response body is the codec-encoded output on success, or anRpcErrorBodyon error with HTTP status mapped via [CoolError::status_code].POST /rpc/batch— sequence ofRpcRequestframes in, sequence ofRpcResponseFrameframes out in the same order. Per-frame errors don’t poison the batch.
Subscriptions and streaming live on WebSocket and application/cbor-seq
respectively; they are deferred to a follow-up patch.
The macro emits the dispatch table and the rpc_router constructor.
This crate provides the shared frame shapes, error mapping, and the
RPC_*_PATH constants both sides agree on.
Structs§
- RpcError
Body - Wire shape of a single error returned by an RPC call. Maps from
CoolErrorviarpc_code+CoolError::public_message. - RpcList
Input - RPC input for
model.<X>.list. Mirrors the REST URL query 1:1 — every optional field maps to a query param of the same name, predicates carry arbitrary(key, value)pairs that aren’t reserved keywords. - RpcList
Predicate - Single arbitrary key/value predicate inside
RpcListInput::filters. Models the REST URL form’s “anything that isn’t a reserved keyword is a predicate” rule (e.g.?published=true&authorId=42). - RpcPk
Input - RPC input for
model.<X>.getandmodel.<X>.delete. The PK type is instantiated per-model at the macro emission site. - RpcRequest
- Wire shape of a single batch request frame.
- RpcResponse
Frame - Wire shape of a single batch response frame.
- RpcUpdate
Input - RPC input for
model.<X>.update. Parameterized on both the PK type and the model’s concreteUpdate<X>Inputso the patch decodes straight to its real type — round-tripping throughserde_json::Valuewould corrupt CBOROption::Nonevalues (whichminicbor-serdeencodes as0xf6simple-null butserde_json::Valueencodes as the CBOR empty-array marker; see comments incratestack-codec-cbor). The dispatcher re-encodespatchthrough the same codec before handing it to the existing update handler.
Constants§
- RPC_
BATCH_ PATH - Mount path for batched RPC calls. Body is a codec-encoded sequence
of
RpcRequestframes. - RPC_
BINDING_ CAPABILITIES - Codec/transport capabilities for every RPC binding route. Both unary and batch accept and emit CBOR or JSON, default CBOR; sequence responses (streaming) are not yet supported by this binding.
- RPC_
UNARY_ PATH - Mount path for unary RPC calls. The trailing segment is the
percent-decoded op id, e.g.
POST /rpc/model.User.list.
Functions§
- convert_
handler_ error_ response - Post-process a handler-emitted response. Success responses pass
through unchanged. Non-2xx responses are buffered, their bodies
decoded as
cratestack_core::CoolErrorResponse(the REST shape the existing axum handlers emit), translated toRpcErrorBodywith the gRPC-style code, and re-encoded with the same HTTP status. - cool_
error_ code_ to_ rpc_ code - Map a
CoolErrorResponse.codestring (screaming-snake, REST- binding vocabulary) to the stable gRPC-style code the RPC binding emits. - decode_
rpc_ body - Decode an RPC unary request body into
T, picking the codec based on the request’sContent-Typeheader. Missing header → CBOR (the default for the REST binding too). - encode_
rpc_ error - Build an
axum::Responsecarrying anRpcErrorBodyfor aCoolErrorraised inside the dispatcher (e.g. body decode failure, unknown op id). The HTTP status comes fromCoolError::status_code; the body is codec-encoded via the request’s codec, content-type negotiated againstRPC_BINDING_CAPABILITIES. - encode_
rpc_ value - Encode an arbitrary serializable value back to bytes using the same
codec as the request. Used by the macro-generated
updatedispatch arm to re-encode the typed patch before handing it to the existing update handler asBytes. - response_
to_ frame - Convert an [
axum::Response] returned by an inner dispatch arm into a single batch response frame. - rpc_
code - Map a
CoolErrorto its stable RPC code (gRPC-style snake_case). - synthesize_
list_ query - Synthesize a URL query string from an
RpcListInputin exactly the shape the macro-generatedparse_model_list_queryparses. ReturnsNonewhen the input has no fields set (the existing handler treats a missing query the same as an empty one — no point allocating).