spacegate_kernel/service/http_gateway/
builder.rs

1use std::{collections::HashMap, sync::Arc};
2
3use hyper::{service::service_fn, Response};
4
5use crate::{
6    helper_layers::{function::FnLayer, reload::Reloader},
7    service::http_route::HttpRoute,
8    utils::Snowflake,
9    ArcHyperService, BoxLayer, SgBody,
10};
11
12use super::{Gateway, HttpRouterService};
13#[derive(Debug)]
14pub struct GatewayBuilder {
15    pub gateway_name: Arc<str>,
16    pub http_routers: HashMap<String, HttpRoute>,
17    pub http_plugins: Vec<BoxLayer>,
18    pub http_fallback: ArcHyperService,
19    pub http_route_reloader: Reloader<HttpRouterService>,
20    pub extensions: hyper::http::Extensions,
21    pub x_request_id: bool,
22}
23
24/// return empty 404 not found
25pub fn default_gateway_route_fallback() -> ArcHyperService {
26    ArcHyperService::new(service_fn(|_| async {
27        Ok(Response::builder().status(hyper::StatusCode::NOT_FOUND).body(SgBody::empty()).expect("bad response"))
28    }))
29}
30
31impl GatewayBuilder {
32    pub fn new(gateway_name: impl Into<Arc<str>>) -> Self {
33        Self {
34            gateway_name: gateway_name.into(),
35            http_routers: HashMap::new(),
36            http_plugins: Vec::new(),
37            http_fallback: default_gateway_route_fallback(),
38            http_route_reloader: Default::default(),
39            extensions: hyper::http::Extensions::default(),
40            x_request_id: true,
41        }
42    }
43    pub fn x_request_id(mut self, enable: bool) -> Self {
44        self.x_request_id = enable;
45        self
46    }
47    pub fn http_router(mut self, route: HttpRoute) -> Self {
48        self.http_routers.insert(route.name.clone(), route);
49        self
50    }
51    pub fn http_routers(mut self, routes: impl IntoIterator<Item = (String, HttpRoute)>) -> Self {
52        for (name, mut route) in routes {
53            route.name.clone_from(&name);
54            self.http_routers.insert(name, route);
55        }
56        self
57    }
58    pub fn http_plugin(mut self, plugin: BoxLayer) -> Self {
59        self.http_plugins.push(plugin);
60        self
61    }
62    pub fn http_plugins(mut self, plugins: impl IntoIterator<Item = BoxLayer>) -> Self {
63        self.http_plugins.extend(plugins);
64        self
65    }
66    pub fn http_fallback(mut self, fallback: ArcHyperService) -> Self {
67        self.http_fallback = fallback;
68        self
69    }
70    pub fn http_route_reloader(mut self, reloader: Reloader<HttpRouterService>) -> Self {
71        self.http_route_reloader = reloader;
72        self
73    }
74    pub fn ext(mut self, extension: hyper::http::Extensions) -> Self {
75        self.extensions = extension;
76        self
77    }
78    pub fn build(self) -> Gateway {
79        let mut plugins = vec![];
80        if self.x_request_id {
81            plugins.push(BoxLayer::new(FnLayer::new_closure(crate::utils::x_request_id::<Snowflake>)));
82        }
83        plugins.extend(self.http_plugins);
84        Gateway {
85            gateway_name: self.gateway_name,
86            http_routes: self.http_routers,
87            http_plugins: plugins,
88            http_fallback: self.http_fallback,
89            http_route_reloader: self.http_route_reloader,
90            ext: self.extensions,
91        }
92    }
93}