cratestack_axum/rpc/mod.rs
1//! Runtime primitives for the `transport rpc` generation style.
2//!
3//! See `docs/design/rpc-transport.md` for the full design. This module
4//! provides the binding-side surface that schemas with `transport rpc`
5//! generate against:
6//!
7//! - `POST /rpc/{op_id}` — unary calls. Body is the codec-encoded *input*
8//! (no frame wrapper); response body is the codec-encoded *output* on
9//! success, or an [`RpcErrorBody`] on error with HTTP status mapped via
10//! [`CoolError::status_code`].
11//! - `POST /rpc/batch` — sequence of `RpcRequest` frames in, sequence of
12//! `RpcResponseFrame` frames out in the same order. Per-frame errors
13//! don't poison the batch.
14//!
15//! Subscriptions and streaming live on WebSocket and `application/cbor-seq`
16//! respectively; they are deferred to a follow-up patch.
17//!
18//! The macro emits the dispatch table and the `rpc_router` constructor.
19//! This crate provides the shared frame shapes, error mapping, and the
20//! `RPC_*_PATH` constants both sides agree on.
21
22mod batch;
23mod codec_helpers;
24mod error_encode;
25mod grpc_bridge;
26mod inputs;
27mod synthesize;
28mod util;
29
30#[cfg(test)]
31mod tests_error;
32#[cfg(test)]
33mod tests_frame;
34#[cfg(test)]
35mod tests_list;
36
37// Re-export the wire shapes from `cratestack-core::rpc`. Both the server
38// binding and every generated client agree on those shapes, and lifting
39// them into core means the client crates don't need to depend on axum.
40pub use cratestack_core::rpc::{
41 RPC_BATCH_PATH, RPC_UNARY_PATH, RpcErrorBody, RpcRequest, RpcResponseFrame,
42 cool_error_code_to_rpc_code, rpc_code,
43};
44
45pub use batch::response_to_frame;
46pub use codec_helpers::{decode_rpc_body, encode_rpc_value};
47pub use error_encode::{convert_handler_error_response, encode_rpc_error};
48pub use grpc_bridge::bridge_grpc_response;
49pub use inputs::{RpcListInput, RpcListPredicate, RpcPkInput, RpcUpdateInput};
50pub use synthesize::synthesize_list_query;
51
52/// Codec/transport capabilities for every RPC binding route. Both unary
53/// and batch accept and emit CBOR or JSON, default CBOR; sequence
54/// responses (streaming) are not yet supported by this binding.
55///
56/// Used by `encode_transport_result_with_status_for` to negotiate
57/// response content type when the dispatcher synthesizes an error
58/// response or wraps a batch result.
59pub const RPC_BINDING_CAPABILITIES: cratestack_core::RouteTransportCapabilities =
60 cratestack_core::RouteTransportCapabilities {
61 request_types: &["application/cbor", "application/json"],
62 response_types: &["application/cbor", "application/json"],
63 default_response_type: "application/cbor",
64 supports_sequence_response: false,
65 };