impulse_server_kit/lib.rs
1//! Impulse Server Kit
2//!
3//! State-of-art simple and powerful web server based on `salvo`. Provides extended tracing, configuration-over-YAML, QUIC/HTTP3, MessagePack support, ACME, OpenAPI and OpenTelemetry features by default, with one step to CORS and WebSockets.
4//!
5//! 4 Quick start steps:
6//!
7//! 1. Create `Setup` struct
8//! 2. Create simple endpoints
9//! 3. Create `server-example.yaml` file in crate root
10//! 4. Just setup your application in 7 lines in `main`
11//!
12//! ```yaml
13//! startup_type: http_localhost
14//! server_port: 8801
15//! allow_oapi_access: true
16//! oapi_frontend_type: Scalar
17//! oapi_name: Server Test OAPI
18//! oapi_ver: 0.0.1
19//! oapi_api_addr: /api
20//! enable_io_logs: true
21//! io_log_level: debug
22//! ```
23//!
24//! ```rust,ignore
25//! // Cargo.toml dependencies:
26//! //
27//! // impulse-server-kit = { git = "https://github.com/impulse-sw/impulse-kit.git", tag = "0.11" }
28//! // serde = { version = "1", features = ["derive"] }
29//! // tokio = { version = "1", features = ["macros"] }
30//! // tracing = "1"
31//!
32//! use impulse_server_kit::prelude::*;
33//! use serde::{Deserialize, Serialize};
34//!
35//! #[derive(Deserialize, Default, Clone)]
36//! struct Setup {
37//! #[serde(flatten)]
38//! generic_values: GenericValues,
39//! // this could be your global variables, such as the database URLs
40//! }
41//!
42//! impl GenericSetup for Setup {
43//! fn generic_values(&self) -> &GenericValues { &self.generic_values }
44//! fn generic_values_mut(&mut self) -> &mut GenericValues { &mut self.generic_values }
45//! }
46//!
47//! #[derive(Deserialize, Serialize, Debug, salvo::oapi::ToSchema)]
48//! /// Some hello
49//! struct HelloData {
50//! /// Hello's text
51//! text: String,
52//! }
53//!
54//! #[endpoint(
55//! tags("test"),
56//! request_body(content = HelloData, content_type = "application/json", description = "Some JSON hello to MsgPack"),
57//! responses((status_code = 200, description = "Some MsgPack hello", body = HelloData, content_type = ["application/msgpack"]))
58//! )]
59//! #[instrument(skip_all, fields(http.uri = req.uri().path(), http.method = req.method().as_str()))]
60//! async fn json_to_msgpack(req: &mut Request, depot: &mut Depot) -> MResult<MsgPack<HelloData>> {
61//! let hello = req.parse_json::<HelloData>().await?;
62//! let app_name = depot.obtain::<Setup>()?.generic_values().app_name.as_str();
63//! msgpack!(HelloData { text: format!("From `{}` application: {}", app_name, hello.text) })
64//! }
65//!
66//! #[endpoint(
67//! tags("test"),
68//! request_body(content = HelloData, content_type = "application/msgpack", description = "Some MsgPack hello to JSON"),
69//! responses((status_code = 200, description = "Some JSON hello", body = HelloData, content_type = ["application/json"]))
70//! )]
71//! #[instrument(skip_all, fields(http.uri = req.uri().path(), http.method = req.method().as_str()))]
72//! async fn msgpack_to_json(req: &mut Request, depot: &mut Depot) -> MResult<Json<HelloData>> {
73//! let hello = req.parse_msgpack::<HelloData>().await?;
74//! let app_name = depot.obtain::<Setup>()?.generic_values().app_name.as_str();
75//! json!(HelloData { text: format!("From `{}` application: {}", app_name, hello.text) })
76//! }
77//!
78//! fn tests_router() -> Router {
79//! Router::new()
80//! .push(Router::with_path("msgpack-to-json").post(msgpack_to_json))
81//! .push(Router::with_path("json-to-msgpack").post(json_to_msgpack))
82//! }
83//!
84//! #[tokio::main]
85//! async fn main() {
86//! let setup = load_generic_config::<Setup>("server-example").await.unwrap();
87//! let state = load_generic_state(&setup, true).await.unwrap();
88//! let router = get_root_router_autoinject(&state, setup.clone()).push(tests_router());
89//! start(state, &setup, router).await.unwrap();
90//! }
91//! ```
92//!
93//! Here we go! You can now start the server with `cargo run --release`!
94
95#![feature(stmt_expr_attributes)]
96#![warn(missing_docs)]
97#![deny(warnings, clippy::todo, clippy::unimplemented)]
98
99pub mod prelude;
100pub mod setup;
101pub mod startup;
102
103pub use salvo;
104
105pub use tracing;
106
107#[cfg(feature = "otel")]
108/// OpenTelemetry libraries' re-export.
109pub mod otel {
110 pub use opentelemetry as api;
111 pub use opentelemetry_otlp as exporter;
112 pub use opentelemetry_sdk as sdk;
113 pub use tracing_opentelemetry as tracing_otel;
114}
115
116pub use impulse_utils;
117
118#[cfg(feature = "test")]
119pub mod test_exts;