Skip to main content

reflectapi/
lib.rs

1//! # `reflectapi` - is a library and a toolkit for writing web API services in Rust and generating compatible clients,
2//! delivering great development experience and efficiency.
3//!
4//! ## Quick start
5//!
6//! Server application side example:
7//! (complete main.rs example can be found in [https://github.com/thepartly/reflectapi/tree/main/reflectapi-demo](https://github.com/thepartly/reflectapi/tree/main/reflectapi-demo))
8//!
9//! ```rust
10//!
11//! #[derive(Debug)]
12//! pub struct AppState {
13//!     pub books: Vec<Book>,
14//! }
15//!
16//! async fn books_list(
17//!     state: std::sync::Arc<AppState>,
18//!     input: proto::Cursor,
19//!     headers: proto::Authorization,
20//! ) -> Result<proto::Items<Book>, proto::BooksListError> {
21//!     unimplemented!("just a demo of API signature")
22//! }
23//!
24//! pub fn builder() -> reflectapi::Builder<std::sync::Arc<AppState>> {
25//!     reflectapi::Builder::new()
26//!         .route(books_list, |b| {
27//!             b.name("books.list").description("List all books")
28//!         })
29//! }
30//!
31//! impl Default for AppState {
32//!     fn default() -> Self {
33//!         Self {
34//!             books: vec![Book {
35//!                 isbn: "978-3-16-148410-0".into(),
36//!                 title: "The Catcher in the Rye".into(),
37//!             }],
38//!         }
39//!     }
40//! }
41//!
42//! #[derive(
43//!    Debug, Clone, serde::Serialize, serde::Deserialize, reflectapi::Input, reflectapi::Output,
44//! )]
45//! pub struct Book {
46//!     /// ISBN - identity
47//!     pub isbn: String,
48//!     /// Title
49//!     pub title: String,
50//! }
51//!
52//! pub mod proto {
53//!     #[derive(serde::Deserialize, reflectapi::Input)]
54//!     pub struct Authorization {
55//!         pub authorization: String,
56//!     }
57//!
58//!     #[derive(serde::Deserialize, reflectapi::Input)]
59//!     pub struct Cursor {
60//!         #[serde(default)]
61//!         pub cursor: Option<String>,
62//!         #[serde(default)]
63//!         pub limit: Option<u32>,
64//!     }
65//!     #[derive(serde::Serialize, reflectapi::Output)]
66//!     pub struct Items<T> {
67//!         pub items: Vec<T>,
68//!         pub pagination: Pagination,
69//!     }
70//!
71//!     #[derive(serde::Serialize, reflectapi::Output)]
72//!     pub struct Pagination {
73//!         pub next_cursor: Option<String>,
74//!         pub prev_cursor: Option<String>,
75//!     }
76//!
77//!     #[derive(serde::Serialize, reflectapi::Output)]
78//!     pub enum BooksListError {
79//!         Unauthorized,
80//!         LimitExceeded { requested: u32, allowed: u32 },
81//!     }
82//!
83//!     impl reflectapi::StatusCode for BooksListError {
84//!         fn status_code(&self) -> http::StatusCode {
85//!             match self {
86//!                 BooksListError::Unauthorized => http::StatusCode::UNAUTHORIZED,
87//!                 BooksListError::LimitExceeded { .. } => http::StatusCode::UNPROCESSABLE_ENTITY,
88//!             }
89//!         }
90//!     }
91//! }
92//! ```
93//!
94//! Generated client in Typescript (one of the languages supported by the codegen) example:
95//!
96//! ```typescript
97//! import { client, match } from './generated';
98//
99//! async function main() {
100//!     const c = client('http://localhost:3000');
101//
102//!     const result = await c.books.list({}, {
103//!         authorization: 'password'
104//!     })
105//!     let { items, pagination } = result.unwrap_ok_or_else((e) => {
106//!         throw match(e.unwrap(), {
107//!             Unauthorized: () => 'NotAuthorized',
108//!             LimitExceeded: ({ requested, allowed }) => `Limit exceeded: ${requested} > ${allowed}`,
109//!         });
110//!     });
111//!     console.log(`items: ${items[0]?.author}`);
112//!     console.log(`next cursor: ${pagination.next_cursor}`);
113//! }
114//
115//! main()
116//!     .then(() => console.log('done'))
117//!     .catch((err) => console.error(err));
118//! ```
119//!
120//! For complete examples, see the [`reflectapi-demo`](https://github.com/thepartly/reflectapi/tree/main/reflectapi-demo) crate which demonstrates:
121//! - Basic CRUD operations
122//! - Tagged enums and discriminated unions
123//! - Generic types and collections
124//! - Error handling
125//! - Multiple serialization formats
126//! - Project structure setup
127//! - Online docs embedding
128//! - And many more features
129//!
130
131mod empty;
132mod impls;
133mod infallible;
134mod option;
135mod traits;
136mod validation;
137
138#[doc(hidden)]
139#[cfg(feature = "rt")]
140pub mod rt;
141
142#[cfg(feature = "builder")]
143pub(crate) mod builder;
144
145#[cfg(feature = "axum")]
146pub mod axum;
147
148#[doc(hidden)]
149#[cfg(feature = "codegen")]
150pub mod codegen;
151
152#[cfg(feature = "builder")]
153pub use builder::{
154    BuildError, BuildErrors, Builder, ContentType, Handler, HandlerCallback, HandlerFuture,
155    IntoResult, RouteBuilder, Router, StatusCode,
156};
157pub use empty::*;
158pub use infallible::*;
159pub use option::*;
160pub use reflectapi_derive::{Input, Output};
161pub use traits::*;
162pub use validation::*;
163
164// Hidden re-exports
165// #[doc(hidden)]
166// pub use builder::*;
167#[doc(hidden)]
168pub use reflectapi_schema::*;