rest_api/
app.rs

1
2use std::convert::Infallible;
3use std::net::SocketAddr;
4
5use super::database::table_schema::SqlTableSchema;
6
7use super::api_http_server::routing::{Route, split_uri_args};
8use super::api_http_server::middleware::Middleware;
9use super::database::interfaces::DatabaseInterface;
10
11use hyper::{Body, Request, Response, StatusCode};
12
13
14pub struct App {
15    pub routes: Vec<Box<dyn Route + Send + Sync>>,
16    pub middleware: Vec<Box<dyn Middleware + Send + Sync>>,
17    pub database_interface: Box<dyn DatabaseInterface + Send + Sync>,
18}
19
20impl App {
21    fn match_route(&self, uri: String) -> Option<&SqlTableSchema> {
22        for route in &self.routes {
23            let route_match = route.matches_uri(uri.clone());
24            if route_match {
25                return Some(route.get_schema())
26            }
27        }
28        None
29    }
30
31    pub async fn handle_http_request(&self, req: Request<Body>, addr: SocketAddr) -> Result<Response<Body>, Infallible> {
32        if req.method() == hyper::Method::OPTIONS {
33            let response = Response::builder()
34                .header("Allow", "OPTIONS, GET, POST, DELETE, PATCH")
35                .header("Accept", "application/json")
36                .body(
37                    Body::empty()
38                );
39            return Ok(response.unwrap())
40        }
41
42        let mut req = req;
43
44        log::info!("{} Request ({}) at {}", req.method(), addr, req.uri());
45
46        let (base_uri, _) = split_uri_args(req.uri().to_string());
47
48        let table_schema = self.match_route(base_uri);
49
50        for middleware in &self.middleware {
51            middleware.process_request(&mut req);
52        }
53
54        let response: Response<Body> = match table_schema {
55            None => {
56                Response::builder()
57                    .status(StatusCode::NOT_FOUND)
58                    .body(
59                        Body::from("Route not found")
60                    ).unwrap()
61            },
62            Some(table_schema) => {
63                self.database_interface.process_api_request(&mut req, table_schema).await
64            }
65        };
66        Ok(response)
67    }
68}