fts_server/
openapi.rs

1use axum::Router;
2use thiserror::Error;
3use utoipa::openapi::security::{HttpAuthScheme, HttpBuilder, SecurityScheme};
4use utoipa::{Modify, OpenApi};
5use utoipa_rapidoc::RapiDoc;
6
7use fts_core::models::{AuctionOutcome, GroupDisplay};
8
9#[derive(Debug, Error)]
10#[allow(dead_code)]
11pub enum Error {
12    #[error("Example error: {0}")]
13    ExampleError(String),
14}
15
16#[derive(OpenApi)]
17#[openapi(
18    paths(
19        super::routes::admin::define_products,
20        super::routes::admin::solve::solve_auctions,
21        super::routes::products::list_products,
22        super::routes::products::get_product,
23        super::routes::products::product_outcomes,
24        super::routes::submission::get_submission,
25        super::routes::submission::put_submission,
26        super::routes::submission::delete_submission,
27        super::routes::auths::post::post_auth,
28        super::routes::auths::get::get_auth,
29        super::routes::auths::put::put_auth,
30        super::routes::auths::delete::delete_auth,
31        super::routes::auths::list::list_auths,
32        super::routes::auths::outcomes::get_outcomes,
33        super::routes::auths::history::get_history,
34        super::routes::costs::post::post_cost,
35        super::routes::costs::get::get_cost,
36        super::routes::costs::put::put_cost,
37        super::routes::costs::delete::delete_cost,
38        super::routes::costs::history::get_history,
39    ),
40    components(schemas(
41        GroupDisplay, // This is not being pulled in automatically, adding it manually
42        AuctionOutcome,
43    )),
44    external_docs(
45        url = "https://flowtrading.forwardmarketdesign.com", description = "📖 Flow Trading Introduction"
46    ),
47    modifiers(&SecurityAddon),
48    security(
49        ("jwt" = []),
50    )
51)]
52/// The OpenAPI spec for the Flow Trading System
53pub struct MarketplaceApi;
54
55struct SecurityAddon;
56
57impl Modify for SecurityAddon {
58    fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
59        let components = openapi.components.as_mut().unwrap(); // we can unwrap safely since there already is components registered.
60        components.add_security_scheme(
61            "jwt",
62            SecurityScheme::Http(
63                HttpBuilder::new()
64                    .scheme(HttpAuthScheme::Bearer)
65                    .bearer_format("JWT")
66                    .build(),
67            ),
68        )
69    }
70}
71pub fn openapi_router() -> Router {
72    RapiDoc::with_url(
73        "/rapidoc",
74        "/api-docs/openapi.json",
75        MarketplaceApi::openapi(),
76    )
77    // rapidoc can be customized according to https://rapidocweb.com/api.html
78    .custom_html(
79        r#"
80<!doctype html> <!-- Important: must specify -->
81<html>
82  <head>
83    <meta charset="utf-8"> <!-- Important: rapi-doc uses utf8 characters -->
84    <script src="https://cdnjs.cloudflare.com/ajax/libs/rapidoc/9.3.8/rapidoc-min.js" integrity="sha512-0ES6eX4K9J1PrIEjIizv79dTlN5HwI2GW9Ku6ymb8dijMHF5CIplkS8N0iFJ/wl3GybCSqBJu8HDhiFkZRAf0g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
85  </head>
86  <body>
87    <rapi-doc spec-url = $specUrl
88        show-method-in-nav-bar = "as-colored-text"
89        use-path-in-nav-bar = "true"
90    ></rapi-doc>
91  </body>
92</html>
93"#,
94    )
95    .into()
96}