axum backend for new http api (#465)

* axum backend
This commit is contained in:
Al Liu 2023-10-20 14:10:05 +08:00 committed by GitHub
parent 64a3436331
commit 98a8855a0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 12 deletions

View File

@ -3,20 +3,25 @@ name = "nomos-http-api"
version = "0.1.0"
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]
async-trait = "0.1"
overwatch-rs = { git = "https://github.com/logos-co/Overwatch", rev = "6e6678b" }
overwatch-derive = { git = "https://github.com/logos-co/Overwatch", rev = "6e6678b" }
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]
axum = "0.6.20"
tokio = { version = "1.32", features = ["full"] }
hyper = { version = "*", features = ["full"] }
utoipa = "3.5"
axum = "0.6"
hyper = { version = "0.14", features = ["full"] }
utoipa-swagger-ui = { version = "4.0", features = ["axum"] }
reqwest = { version = "0.11", features = ["blocking", "json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
utoipa-swagger-ui = { version = "3.1", features = ["axum"] }

View File

@ -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
}
}

View File

@ -0,0 +1,2 @@
#[cfg(feature = "axum")]
pub mod axum;

View File

@ -0,0 +1 @@
pub mod backend;

View File

@ -8,6 +8,8 @@ use overwatch_rs::{
DynError,
};
pub mod http;
/// A simple abstraction so that we can easily
/// change the underlying http server
#[async_trait::async_trait]

View File

@ -133,7 +133,7 @@ mod todo {
};
use hyper::{HeaderMap, StatusCode};
use serde::{Deserialize, Serialize};
use tokio::sync::Mutex;
use std::sync::Mutex;
use utoipa::{IntoParams, ToSchema};
/// In-memory todo store
@ -173,7 +173,7 @@ mod 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)
}
@ -207,7 +207,7 @@ mod todo {
Json(
store
.lock()
.await
.unwrap()
.iter()
.filter(|todo| {
todo.value.to_lowercase() == query.value.to_lowercase()
@ -234,7 +234,7 @@ mod todo {
State(store): State<Arc<Store>>,
Json(todo): Json<Todo>,
) -> impl IntoResponse {
let mut todos = store.lock().await;
let mut todos = store.lock().unwrap();
todos
.iter_mut()
@ -284,7 +284,7 @@ mod todo {
Err(_) => return StatusCode::UNAUTHORIZED,
}
let mut todos = store.lock().await;
let mut todos = store.lock().unwrap();
todos
.iter_mut()
@ -324,7 +324,7 @@ mod todo {
Err(error) => return error.into_response(),
}
let mut todos = store.lock().await;
let mut todos = store.lock().unwrap();
let len = todos.len();