Skip to main content

solti_api/
lib.rs

1//! # solti-api - task management API.
2//!
3//! Dual-transport API layer exposing task operations over gRPC and HTTP.
4//! Both transports share the same wire types generated from `proto/solti/v1/*.proto` and delegate to an [`ApiHandler`] implementation.
5//!
6//! | feature | transport         | module                              |
7//! |---------|-------------------|-------------------------------------|
8//! | `grpc`  | tonic gRPC server | `SoltiApiService`, `SoltiApiServer` |
9//! | `http`  | axum HTTP/JSON    | `HttpApi`                           |
10//!
11//! ## Quick start
12//!
13//! ```text
14//! let adapter = SupervisorApiAdapter::new(supervisor);
15//! let svc     = SoltiApiServer::new(SoltiApiService::new(Arc::new(adapter)));
16//! let router  = HttpApi::new(Arc::new(adapter)).router();
17//! ```
18//!
19//! ## Also
20//!
21//! - [`ApiHandler`] transport-agnostic trait with 6 operations.
22//! - [`ApiError`] unified error type mapped to gRPC Status / HTTP JSON.
23//! - [`SupervisorApiAdapter`] default adapter bridging to `SupervisorApi`.
24
25#[doc(hidden)]
26#[macro_export]
27macro_rules! solti_api_major {
28    () => {
29        1
30    };
31}
32
33/// Compose a compile-time URL path rooted at `/api/v<API_MAJOR>`.
34#[cfg(feature = "http")]
35#[doc(hidden)]
36#[macro_export]
37macro_rules! api_url {
38    ($path:literal) => {
39        concat!("/api/v", $crate::solti_api_major!(), $path)
40    };
41}
42
43/// Current API protocol version.
44pub const API_VERSION: u32 = solti_api_major!();
45
46/// Maximum accepted request body / message size for both HTTP and gRPC transports. **4 MiB.**
47pub const MAX_REQUEST_BYTES: usize = 4 * 1024 * 1024;
48
49mod error;
50pub use error::ApiError;
51
52mod handler;
53pub use handler::ApiHandler;
54
55mod adapter;
56pub use adapter::SupervisorApiAdapter;
57
58#[cfg(any(feature = "grpc", feature = "http"))]
59#[cfg_attr(not(feature = "grpc"), allow(dead_code))]
60pub(crate) mod proto_api {
61    include!(concat!(
62        env!("OUT_DIR"),
63        "/solti.v",
64        solti_api_major!(),
65        ".rs"
66    ));
67
68    #[cfg(feature = "http")]
69    include!(concat!(
70        env!("OUT_DIR"),
71        "/solti.v",
72        solti_api_major!(),
73        ".serde.rs"
74    ));
75}
76
77#[cfg(any(feature = "grpc", feature = "http"))]
78mod convert;
79
80#[cfg(any(feature = "grpc", feature = "http"))]
81mod validate;
82
83#[cfg(feature = "grpc")]
84mod grpc;
85
86#[cfg(feature = "grpc")]
87pub use grpc::{SoltiApiService, build_grpc_server};
88
89#[cfg(feature = "grpc")]
90pub use proto_api::solti_api_server::SoltiApiServer;
91
92#[cfg(feature = "grpc")]
93pub use tonic;
94
95#[cfg(feature = "http")]
96mod http;
97
98#[cfg(feature = "http")]
99pub use http::HttpApi;
100
101#[cfg(feature = "http")]
102pub use axum;
103
104#[cfg(all(test, any(feature = "grpc", feature = "http")))]
105mod api_major_guard {
106    #[test]
107    fn api_major_matches_build_rs() {
108        assert_eq!(
109            super::API_VERSION.to_string(),
110            env!("SOLTI_API_MAJOR"),
111            "lib.rs solti_api_major!() must match build.rs API_MAJOR",
112        );
113    }
114}