1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
//! # 📦 Rust Microservice
//!
//! **Rust Microservice Framework** is a high-performance Rust crate designed to simplify
//! the creation, configuration, and initialization of microservice-oriented web servers.
//! It provides a unified system for handling configuration from multiple sources
//! and a web server bootstrap layer powered by `actix-web` and `tokio`.
//!
//! ## ✨ Features
//!
//! - **Multi-source configuration management**
//! - YAML configuration file loading using `serde_yaml` and `config`
//! - Environment variable overrides
//! - Command-line parameter parsing using `clap`
//! - Automatic deserialization into strongly typed structures using `serde`
//!
//! - **Web server initialization**
//! - HTTP server powered by `actix-web`
//! - Asynchronous runtime handled by `tokio`
//! - Built-in routing integration for exposing microservice endpoints
//! - Input/output serialization using `serde_json` and `serde-xml-rs`
//!
//! - **Extensible architecture**
//! - Supports custom modules for controllers, services, repositories, and middleware
//! - Easy integration with external crates and microservice ecosystems
//!
//! ## 🛠️ Configuration System
//!
//! The framework provides a configuration loader that merges settings from:
//!
//! 1. **YAML files** – typically `config.yaml` or environment-specific variations
//! 2. **Environment variables** – allowing container-friendly overrides
//! 3. **Command-line parameters** – using `clap` for high-level CLI ergonomics
//!
//! Configuration sources follow a layered precedence model:
//!
//! ```text
//! Environment variables > CLI parameters > YAML configuration file
//! ```
//! After loading the configuration, the framework exposes a typed `Settings`
//! instance for application modules and endpoint handlers.
//!
//! ## 🌐 Web SERVER Module
//!
//! The server module is responsible for:
//!
//! - Initializing the `actix-web` HTTP server
//! - Registering routers and microservice endpoints
//! - Managing middlewares and shared application state
//! - Running the asynchronous runtime using `tokio::main` or a custom runtime
//!
//! This framework encourages a modular architecture where each microservice
//! registers its own route handlers, serializers, and business logic.
//!
//! ## ⚙️ Serialization Support
//!
//! The crate includes seamless integration with:
//!
//! - **JSON** serialization/deserialization via `serde_json`
//! - **XML** handling via `serde-xml-rs`
//!
//! These serializers allow exposing multiple content-types or supporting legacy systems.
//!
//! ## ⚡ Usage
//!
//! Add the crate dependency in your project's `Cargo.toml`:
//!
//! ```toml
//! rust-microservice = "0.1.3"
//! ```
pub ;
pub use ServerWrappers;
pub use create_server_wrappers as server_wrappers;
pub use LoginForm;
pub use Token;
pub use Result;
pub use Server;
pub use ServerError;
/// # 🔗 API Server Macro
///
/// The `api_server` macro is a procedural macro that generates the code necessary to
/// start an `actix-web` HTTP server with support for OpenAPI documentation and
/// a health check endpoint.
///
/// The `api_server` macro takes the following attributes:
///
/// - `controllers_path`: A comma-separated list of paths to modules containing
/// controllers. The macro will recursively traverse the directories and generate
/// code to register the controllers with the HTTP server.
///
/// - `openapi_title`: A string used as the title of the OpenAPI documentation.
///
/// - `openapi_api_description`: A string used as the description of the OpenAPI
/// documentation.
///
/// - `database`: A boolean indicating whether the microservice should enable database
/// integration. If set to `true`, the macro will generate code to initialize the
/// database connection pool using the `sea_orm` crate.
///
/// - `banner`: A string used as the banner of the microservice. The banner is displayed
/// in the server logs during startup.
///
/// Example of a minimal server bootstrap using this crate:
///
/// ```rust
/// use rust_microservice::ServerApi;
///
/// #[ServerApi(
/// controllers_path = "src/module, src/controllers",
/// openapi_title = "🌐 Rest API Server",
/// openapi_api_description = "Rest API OpenApi Documentation built with Rust 🦀.",
/// database = "true",
/// banner = r#"
/// _~^~^~_ ___ ___ ____ ____
/// \) / o o \ (/ / _ | / _ \ / _/ / __/___ ____ _ __ ___ ____
/// '_ - _' / __ | / ___/_/ / _\ \ / -_)/ __/| |/ //! -_)/ __/
/// / '-----' \ /_/ |_|/_/ /___/ /___/ \__//!_/ |___/ \__//!_/
/// "#
/// )]
/// async fn start_server() -> rust_microservice::Result<(), String> {}
/// ```
pub use api_server as ServerApi;
/// # 🛢️ Database Macro
///
/// The `database` macro is a procedural macro that injects a database connection
/// into repository methods.
///
/// It expects two mandatory attributes:
/// - `name`: selects which configured database connection will be used.
/// - `error`: defines the error variant returned when the database is not configured or
/// database connection cannot be found.
///
/// The macro injects a variable named `db` with type `&DatabaseConnection` (seaorm),
/// so the function body can execute queries directly.
///
/// Example:
///
/// ```rust
/// use rust_microservice::{Server, database};
/// use thiserror::Error;
///
/// #[derive(Debug, Error)]
/// pub enum UserError {
/// #[error("Database is not configured")]
/// DatabaseNotConfigured,
///
/// #[error("User not found")]
/// NotFound,
/// }
///
/// pub type Result<T, E = UserError> = std::result::Result<T, E>;
///
/// #[database(name = "api", error = "UserError::DatabaseNotConfigured")]
/// pub async fn get_user_by_id(user_id: i32) -> Result<()> {
///
/// // Database will be injected here as `db`
///
/// //user::Entity::find_by_id(user_id)
/// // .one(&db)
/// // .await
/// // .map_err(|_| UserError::NotFound)?
/// // .ok_or(UserError::NotFound)
/// // .map(Into::into)
///
/// Ok(())
/// }
/// ```
pub use database;
/// # 🔐 Secured Macro
///
/// The `Secured` macro protects `actix-web` endpoints by attaching an authentication middleware.
///
/// When applied to an endpoint, it validates:
///
/// - JWT presence in the request.
/// - JWT signature.
/// - JWT expiration time (`exp` claim).
/// - JWT issuer (`iss` claim).
/// - Required roles from the `authorize` expression.
///
/// ## Attribute Reference
//
/// Macro usage format:
//
/// ```no_run
/// #[secured(method = "...", path = "...", authorize = "...")]
/// ```
///
/// ### **`method`**
///
/// Defines the HTTP method used to map the endpoint in Actix-Web.
///
/// Supported values:
///
/// - `get`
/// - `post`
/// - `put`
/// - `delete`
/// - `head`
/// - `connect`
/// - `options`
/// - `trace`
/// - `patch`
///
/// ### **`path`**
///
/// Defines the endpoint path to be registered by Actix-Web.
///
/// Example:
///
/// `path = "/v1/user/{id}"`
///
/// ### **`authorize`**
///
/// Defines the required role rule that must be satisfied by roles present in the JWT.
///
/// Supported formats:
///
/// 1. `Single role`: validates one role in the token.
///
/// `authorize = "ROLE_ADMIN"`
///
/// 2. `hasAnyRole`: validates that at least one role in the list exists in the token.
///
/// `authorize = "hasAnyRole(ROLE_ADMIN, ROLE_USER)"`
///
/// 3. `hasAllRoles`: validates that all roles in the list exist in the token.
///
/// `authorize = "hasAllRoles(ROLE_ADMIN, ROLE_USER)"`
///
/// ## Examples
///
/// ### **`Single role`**:
///
/// ```no_run
/// use rust_microservice::secured;
/// use actix_web::{HttpResponse, delete, get, http::StatusCode, post, put, web};
///
/// #[secured(method = "post", path = "/v1/user", authorize = "ROLE_ADMIN")]
/// pub async fn create_user_endpoint() -> HttpResponse {
/// // handler body
/// HttpResponse::Ok().finish()
/// }
/// ```
///
/// ### **`Any role`**:
///
/// ```no_run
/// use rust_microservice::secured;
/// use actix_web::{HttpResponse, delete, get, http::StatusCode, post, put, web};
///
/// #[secured(
/// method = "get",
/// path = "/v1/user/{id}",
/// authorize = "hasAnyRole(ROLE_ADMIN, ROLE_USER)"
/// )]
/// pub async fn get_user_endpoint() -> HttpResponse {
/// // handler body
/// HttpResponse::Ok().finish()
/// }
/// ```
///
/// ### **`All roles`**:
///
/// ```no_run
/// use rust_microservice::secured;
/// use actix_web::{HttpResponse, delete, get, http::StatusCode, post, put, web};
///
/// #[secured(
/// method = "delete",
/// path = "/v1/user/{id}",
/// authorize = "hasAllRoles(ROLE_ADMIN, ROLE_AUDITOR)"
/// )]
/// pub async fn delete_user_endpoint() -> HttpResponse {
/// // handler body
/// HttpResponse::Ok().finish()
/// }
/// ```
pub use secured;