Skip to main content

Module rpc

Module rpc 

Source
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 an RpcErrorBody on error with HTTP status mapped via [CoolError::status_code].
  • POST /rpc/batch — sequence of RpcRequest frames in, sequence of RpcResponseFrame frames 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§

RpcErrorBody
Wire shape of a single error returned by an RPC call. Maps from CoolError via rpc_code + CoolError::public_message.
RpcListInput
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.
RpcListPredicate
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).
RpcPkInput
RPC input for model.<X>.get and model.<X>.delete. The PK type is instantiated per-model at the macro emission site.
RpcRequest
Wire shape of a single batch request frame.
RpcResponseFrame
Wire shape of a single batch response frame.
RpcUpdateInput
RPC input for model.<X>.update. Parameterized on both the PK type and the model’s concrete Update<X>Input so the patch decodes straight to its real type — round-tripping through serde_json::Value would corrupt CBOR Option::None values (which minicbor-serde encodes as 0xf6 simple-null but serde_json::Value encodes as the CBOR empty-array marker; see comments in cratestack-codec-cbor). The dispatcher re-encodes patch through 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 RpcRequest frames.
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 to RpcErrorBody with the gRPC-style code, and re-encoded with the same HTTP status.
cool_error_code_to_rpc_code
Map a CoolErrorResponse.code string (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’s Content-Type header. Missing header → CBOR (the default for the REST binding too).
encode_rpc_error
Build an axum::Response carrying an RpcErrorBody for a CoolError raised inside the dispatcher (e.g. body decode failure, unknown op id). The HTTP status comes from CoolError::status_code; the body is codec-encoded via the request’s codec, content-type negotiated against RPC_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 update dispatch arm to re-encode the typed patch before handing it to the existing update handler as Bytes.
response_to_frame
Convert an [axum::Response] returned by an inner dispatch arm into a single batch response frame.
rpc_code
Map a CoolError to its stable RPC code (gRPC-style snake_case).
synthesize_list_query
Synthesize a URL query string from an RpcListInput in exactly the shape the macro-generated parse_model_list_query parses. Returns None when the input has no fields set (the existing handler treats a missing query the same as an empty one — no point allocating).