parent
64a3436331
commit
98a8855a0e
|
@ -3,20 +3,25 @@ name = "nomos-http-api"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
[features]
|
||||||
|
axum = ["dep:axum", "dep:hyper", "utoipa-swagger-ui/axum"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
overwatch-rs = { git = "https://github.com/logos-co/Overwatch", rev = "6e6678b" }
|
overwatch-rs = { git = "https://github.com/logos-co/Overwatch", rev = "6e6678b" }
|
||||||
overwatch-derive = { git = "https://github.com/logos-co/Overwatch", rev = "6e6678b" }
|
overwatch-derive = { git = "https://github.com/logos-co/Overwatch", rev = "6e6678b" }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
utoipa = "4.0"
|
||||||
|
utoipa-swagger-ui = { version = "4.0" }
|
||||||
|
|
||||||
|
# axum related dependencies
|
||||||
|
axum = { version = "0.6", optional = true }
|
||||||
|
hyper = { version = "0.14", features = ["full"], optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
axum = "0.6.20"
|
axum = "0.6"
|
||||||
tokio = { version = "1.32", features = ["full"] }
|
hyper = { version = "0.14", features = ["full"] }
|
||||||
hyper = { version = "*", features = ["full"] }
|
utoipa-swagger-ui = { version = "4.0", features = ["axum"] }
|
||||||
utoipa = "3.5"
|
|
||||||
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
utoipa-swagger-ui = { version = "3.1", features = ["axum"] }
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
use std::{net::SocketAddr, sync::Arc};
|
||||||
|
|
||||||
|
use axum::{Router, Server};
|
||||||
|
use utoipa::OpenApi;
|
||||||
|
use utoipa_swagger_ui::SwaggerUi;
|
||||||
|
|
||||||
|
use crate::Backend;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct AxumBackendSettings {
|
||||||
|
pub addr: SocketAddr,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AxumBackend {
|
||||||
|
settings: Arc<AxumBackendSettings>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(OpenApi)]
|
||||||
|
#[openapi(paths(), components(), tags())]
|
||||||
|
struct ApiDoc;
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl Backend for AxumBackend {
|
||||||
|
type Error = hyper::Error;
|
||||||
|
type Settings = AxumBackendSettings;
|
||||||
|
|
||||||
|
async fn new(settings: Self::Settings) -> Result<Self, Self::Error>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
Ok(Self {
|
||||||
|
settings: Arc::new(settings),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn serve(self) -> Result<(), Self::Error> {
|
||||||
|
let store = self.settings.clone();
|
||||||
|
let app = Router::new()
|
||||||
|
.merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi()))
|
||||||
|
.with_state(store);
|
||||||
|
|
||||||
|
Server::bind(&self.settings.addr)
|
||||||
|
.serve(app.into_make_service())
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
#[cfg(feature = "axum")]
|
||||||
|
pub mod axum;
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod backend;
|
|
@ -8,6 +8,8 @@ use overwatch_rs::{
|
||||||
DynError,
|
DynError,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod http;
|
||||||
|
|
||||||
/// A simple abstraction so that we can easily
|
/// A simple abstraction so that we can easily
|
||||||
/// change the underlying http server
|
/// change the underlying http server
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
|
|
|
@ -133,7 +133,7 @@ mod todo {
|
||||||
};
|
};
|
||||||
use hyper::{HeaderMap, StatusCode};
|
use hyper::{HeaderMap, StatusCode};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use utoipa::{IntoParams, ToSchema};
|
use utoipa::{IntoParams, ToSchema};
|
||||||
|
|
||||||
/// In-memory todo store
|
/// In-memory todo store
|
||||||
|
@ -173,7 +173,7 @@ mod todo {
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub(super) async fn list_todos(State(store): State<Arc<Store>>) -> Json<Vec<Todo>> {
|
pub(super) async fn list_todos(State(store): State<Arc<Store>>) -> Json<Vec<Todo>> {
|
||||||
let todos = store.lock().await.clone();
|
let todos = store.lock().unwrap().clone();
|
||||||
|
|
||||||
Json(todos)
|
Json(todos)
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,7 @@ mod todo {
|
||||||
Json(
|
Json(
|
||||||
store
|
store
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|todo| {
|
.filter(|todo| {
|
||||||
todo.value.to_lowercase() == query.value.to_lowercase()
|
todo.value.to_lowercase() == query.value.to_lowercase()
|
||||||
|
@ -234,7 +234,7 @@ mod todo {
|
||||||
State(store): State<Arc<Store>>,
|
State(store): State<Arc<Store>>,
|
||||||
Json(todo): Json<Todo>,
|
Json(todo): Json<Todo>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let mut todos = store.lock().await;
|
let mut todos = store.lock().unwrap();
|
||||||
|
|
||||||
todos
|
todos
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
@ -284,7 +284,7 @@ mod todo {
|
||||||
Err(_) => return StatusCode::UNAUTHORIZED,
|
Err(_) => return StatusCode::UNAUTHORIZED,
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut todos = store.lock().await;
|
let mut todos = store.lock().unwrap();
|
||||||
|
|
||||||
todos
|
todos
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
@ -324,7 +324,7 @@ mod todo {
|
||||||
Err(error) => return error.into_response(),
|
Err(error) => return error.into_response(),
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut todos = store.lock().await;
|
let mut todos = store.lock().unwrap();
|
||||||
|
|
||||||
let len = todos.len();
|
let len = todos.len();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue