added base for openapi & swaggerui
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
use crate::base::{entity::BaseEntity, i_service::IBaseService};
|
||||
use anyhow::Result;
|
||||
use axum::{http::StatusCode, response::IntoResponse, Json};
|
||||
use axum::{extract::State, http::StatusCode, response::IntoResponse, routing::get, Json, Router};
|
||||
use diesel::Identifiable;
|
||||
use serde::Serialize;
|
||||
use std::marker::PhantomData;
|
||||
use crate::base::{entity::BaseEntity, i_service::IBaseService};
|
||||
use std::{marker::PhantomData, ops::Deref, sync::Arc};
|
||||
|
||||
pub struct BaseController<T, S>
|
||||
where
|
||||
@@ -27,7 +27,28 @@ where
|
||||
}
|
||||
|
||||
pub async fn get_all(&self) -> Result<impl IntoResponse, String> {
|
||||
let entities = self.service.get_all().await.map_err(|err| err.to_string())?;
|
||||
let entities = self
|
||||
.service
|
||||
.get_all()
|
||||
.await
|
||||
.map_err(|err| err.to_string())?;
|
||||
Ok((StatusCode::OK, Json(entities)))
|
||||
}
|
||||
|
||||
pub fn default_routes<C>(controller: Arc<C>, base_path: &str) -> Router
|
||||
where
|
||||
C: Deref<Target = Self> + Send + Sync + 'static,
|
||||
{
|
||||
Router::new()
|
||||
.route(
|
||||
&format!("{}", base_path),
|
||||
get(|State(controller): State<Arc<C>>| async move {
|
||||
controller
|
||||
.get_all()
|
||||
.await
|
||||
.map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, Json(err)))
|
||||
}),
|
||||
)
|
||||
.with_state(controller)
|
||||
}
|
||||
}
|
||||
|
30
src/main.rs
30
src/main.rs
@@ -1,11 +1,16 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::routes::user::controller::UserController;
|
||||
use crate::routes::user::model::{User, UserResponse};
|
||||
use crate::routes::user::service::UserService;
|
||||
use axum::http::StatusCode;
|
||||
use axum::routing::get;
|
||||
use axum::{serve, Router};
|
||||
use config::db::init_db;
|
||||
use dotenvy::dotenv;
|
||||
use tokio::net::TcpListener;
|
||||
use crate::routes::user::controller::UserController;
|
||||
use crate::routes::user::service::UserService;
|
||||
use utoipa::OpenApi;
|
||||
use utoipa_swagger_ui::SwaggerUi;
|
||||
|
||||
mod base;
|
||||
mod config;
|
||||
@@ -16,12 +21,31 @@ async fn main() {
|
||||
dotenv().ok();
|
||||
let pool = init_db();
|
||||
|
||||
let hc_router = Router::new().route("/", get(health_check));
|
||||
|
||||
let user_service = UserService::new(pool);
|
||||
let user_controller = Arc::new(UserController::new(user_service));
|
||||
|
||||
let app = Router::new()
|
||||
.merge(UserController::routes(user_controller.clone()));
|
||||
.merge(UserController::routes(user_controller.clone()))
|
||||
.merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi()))
|
||||
.nest("/hc", hc_router);
|
||||
|
||||
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
serve(listener, app).await.unwrap();
|
||||
|
||||
async fn health_check() -> StatusCode {
|
||||
StatusCode::OK
|
||||
}
|
||||
|
||||
#[derive(OpenApi)]
|
||||
#[openapi(
|
||||
components(
|
||||
schemas(User, UserResponse)
|
||||
),
|
||||
tags(
|
||||
(name = "users", description = "User management endpoints")
|
||||
)
|
||||
)]
|
||||
struct ApiDoc;
|
||||
}
|
||||
|
@@ -1,11 +1,8 @@
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::extract::State;
|
||||
use axum::http::StatusCode;
|
||||
use axum::response::IntoResponse;
|
||||
use axum::{Json, Router};
|
||||
use axum::routing::get;
|
||||
use crate::base::controller::BaseController;
|
||||
use axum::Router;
|
||||
|
||||
use super::model::User;
|
||||
use super::service::UserService;
|
||||
@@ -14,6 +11,14 @@ pub struct UserController {
|
||||
base_controller: BaseController<User, UserService>,
|
||||
}
|
||||
|
||||
impl Deref for UserController {
|
||||
type Target = BaseController<User, UserService>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.base_controller
|
||||
}
|
||||
}
|
||||
|
||||
impl UserController {
|
||||
pub fn new(service: UserService) -> Self {
|
||||
Self {
|
||||
@@ -21,17 +26,19 @@ impl UserController {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn routes(state: Arc<UserController>) -> Router {
|
||||
Router::new()
|
||||
.route("/users", get(Self::get_users))
|
||||
.with_state(state)
|
||||
pub fn routes(controller: Arc<Self>) -> Router {
|
||||
BaseController::default_routes(controller, "/users")
|
||||
}
|
||||
|
||||
/*
|
||||
async fn get_users(
|
||||
State(controller): State<Arc<UserController>>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<String>)> {
|
||||
controller.base_controller.get_all().await.map_err(|err| {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(err))
|
||||
})
|
||||
controller
|
||||
.base_controller
|
||||
.get_all()
|
||||
.await
|
||||
.map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, Json(err)))
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@@ -1,9 +1,10 @@
|
||||
use super::schema::users;
|
||||
use crate::base::entity::BaseEntity;
|
||||
use diesel::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::base::entity::BaseEntity;
|
||||
use super::schema::users;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Queryable, Identifiable)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Queryable, Identifiable, ToSchema)]
|
||||
#[diesel(table_name = users, primary_key(id))]
|
||||
pub struct User {
|
||||
pub id: i32,
|
||||
@@ -11,6 +12,13 @@ pub struct User {
|
||||
pub email: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, ToSchema)]
|
||||
pub struct UserResponse {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub email: String,
|
||||
}
|
||||
|
||||
impl BaseEntity for User {
|
||||
fn id(&self) -> i32 {
|
||||
self.id
|
||||
@@ -23,4 +31,5 @@ impl Identifiable for User {
|
||||
fn id(self) -> Self::Id {
|
||||
self.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user