use log::info; use okapi::openapi3::OpenApi; use rocket::http::Method; use rocket::{Build, Request, Rocket}; use rocket_cors::{AllowedHeaders, AllowedOrigins}; use rocket_okapi::swagger_ui::make_swagger_ui; use crate::country_statistics::http::country_statistics_make_default_routes; use crate::gateways::http::gateways_make_default_routes; use crate::http::swagger::get_docs; use crate::mix_node::http::mix_node_make_default_routes; use crate::mix_nodes::http::mix_nodes_make_default_routes; use crate::overview::http::overview_make_default_routes; use crate::ping::http::ping_make_default_routes; use crate::service_providers::http::service_providers_make_default_routes; use crate::state::ExplorerApiStateContext; use crate::validators::http::validators_make_default_routes; mod swagger; pub(crate) fn start(state: ExplorerApiStateContext) { tokio::spawn(async move { info!("Starting up..."); configure_rocket(state).launch().await }); } fn configure_rocket(state: ExplorerApiStateContext) -> Rocket { let allowed_origins = AllowedOrigins::all(); // You can also deserialize this let cors = rocket_cors::CorsOptions { allowed_origins, allowed_methods: vec![Method::Get].into_iter().map(From::from).collect(), allowed_headers: AllowedHeaders::some(&["*"]), allow_credentials: true, ..Default::default() } .to_cors() .unwrap(); let openapi_settings = rocket_okapi::settings::OpenApiSettings::default(); let config = rocket::config::Config::release_default(); let mut building_rocket = rocket::build().configure(config); let custom_route_spec = (vec![], custom_openapi_spec()); mount_endpoints_and_merged_docs! { building_rocket, "/v1".to_owned(), openapi_settings, "/" => custom_route_spec, "/countries" => country_statistics_make_default_routes(&openapi_settings), "/gateways" => gateways_make_default_routes(&openapi_settings), "/mix-node" => mix_node_make_default_routes(&openapi_settings), "/mix-nodes" => mix_nodes_make_default_routes(&openapi_settings), "/overview" => overview_make_default_routes(&openapi_settings), "/ping" => ping_make_default_routes(&openapi_settings), "/validators" => validators_make_default_routes(&openapi_settings), "/service-providers" => service_providers_make_default_routes(&openapi_settings), }; building_rocket .mount("/swagger", make_swagger_ui(&get_docs())) .register("/", catchers![not_found]) .manage(state) .attach(cors) } #[catch(404)] pub(crate) fn not_found(req: &Request<'_>) -> String { format!("I couldn't find '{}'. Try something else?", req.uri()) } fn custom_openapi_spec() -> OpenApi { use rocket_okapi::okapi::openapi3::*; OpenApi { openapi: OpenApi::default_version(), info: Info { title: "Network Explorer API".to_owned(), description: None, terms_of_service: None, contact: None, license: None, version: env!("CARGO_PKG_VERSION").to_owned(), ..Default::default() }, servers: get_servers(), ..Default::default() } } fn get_servers() -> Vec { if std::env::var_os("CARGO").is_some() { return vec![]; } vec![rocket_okapi::okapi::openapi3::Server { url: std::env::var("OPEN_API_BASE").unwrap_or_else(|_| "/api/v1/".to_owned()), description: Some("API".to_owned()), ..Default::default() }] }