feat: initial API and docs
This commit is contained in:
parent
79be4eb543
commit
5d709d658b
16 changed files with 3169 additions and 342 deletions
101
src/main.rs
101
src/main.rs
|
|
@ -1,3 +1,100 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::{extract::State, http::HeaderMap, routing::get};
|
||||
use reqwest::{header::USER_AGENT};
|
||||
use sea_orm::{ConnectionTrait, Database, DatabaseConnection, EntityTrait, PaginatorTrait, Schema};
|
||||
use utoipa::openapi::{ContactBuilder, InfoBuilder, LicenseBuilder};
|
||||
use utoipa_axum::router::OpenApiRouter;
|
||||
use utoipa_redoc::{Redoc, Servable};
|
||||
use utoipa_swagger_ui::{Config, SwaggerUi};
|
||||
use utoipa_axum::routes;
|
||||
|
||||
use crate::entities::prelude::BookInstance;
|
||||
|
||||
pub mod entities;
|
||||
pub mod utils;
|
||||
pub mod routes;
|
||||
|
||||
pub struct AppState {
|
||||
app_name: String,
|
||||
db_conn: Arc<DatabaseConnection>,
|
||||
web_client: reqwest::Client
|
||||
}
|
||||
|
||||
async fn index(
|
||||
State(state): State<Arc<AppState>>
|
||||
) ->String {
|
||||
let app_name = &state.app_name;
|
||||
let db_conn = &state.db_conn;
|
||||
let status: &str = match db_conn.ping().await {
|
||||
Ok(_) => "working",
|
||||
Err(_) => "erroring"
|
||||
};
|
||||
let book_count = BookInstance::find().count(db_conn.as_ref()).await.unwrap();
|
||||
format!("Hello from {app_name}! Database is {status}. We currently have {book_count} books in stock !")
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let db: Arc<DatabaseConnection> = Arc::new(Database::connect(String::from("sqlite://./alexandria.db?mode=rwc")).await.unwrap());
|
||||
|
||||
let builder = db.get_database_backend();
|
||||
let schema = Schema::new(builder);
|
||||
if let Err(err) = db.execute(builder.build(schema.create_table_from_entity(crate::entities::prelude::Book).if_not_exists())).await {
|
||||
println!("Error while creating book table: {err:?}");
|
||||
return;
|
||||
}
|
||||
if let Err(err) = db.execute(builder.build(schema.create_table_from_entity(crate::entities::prelude::BookInstance).if_not_exists())).await {
|
||||
println!("Error while creating book_instance table: {err:?}");
|
||||
return;
|
||||
}
|
||||
if let Err(err) = db.execute(builder.build(schema.create_table_from_entity(crate::entities::prelude::Owner).if_not_exists())).await {
|
||||
println!("Error while creating owner table: {err:?}");
|
||||
return;
|
||||
}
|
||||
|
||||
let mut default_headers = HeaderMap::new();
|
||||
default_headers.append(USER_AGENT, "Alexandria/1.0 (unionetudianteauvergne@gmail.com)".parse().unwrap());
|
||||
let shared_state = Arc::new(AppState {
|
||||
app_name: "Alexandria".to_string(),
|
||||
db_conn: db,
|
||||
web_client: reqwest::Client::builder().default_headers(default_headers).build().expect("creating the reqwest client failed")
|
||||
});
|
||||
|
||||
let (router, mut api) = OpenApiRouter::new()
|
||||
.routes(routes!(routes::book::get_book_by_ean))
|
||||
.routes(routes!(routes::book::get_book_by_id))
|
||||
.routes(routes!(routes::book_instance::get_book_instance_by_id))
|
||||
.routes(routes!(routes::book_instance::create_book_instance))
|
||||
.routes(routes!(routes::owner::get_owner_by_id))
|
||||
.routes(routes!(routes::owner::create_owner))
|
||||
.route("/", get(index))
|
||||
.with_state(shared_state)
|
||||
.split_for_parts();
|
||||
|
||||
api.info = InfoBuilder::new()
|
||||
.title("Alexandria")
|
||||
.description(Some("Alexandria is a server that manages books and users for Union Étudiante's book exchange"))
|
||||
.contact(Some(ContactBuilder::new()
|
||||
.url(Some("https://ueauvergne.fr"))
|
||||
.name(Some("Union Étudiante Auvergne"))
|
||||
.email(Some("unionetudianteauvergne@gmail.com"))
|
||||
.build()))
|
||||
.license(Some(LicenseBuilder::new().name("MIT").url(Some("https://spdx.org/licenses/MIT.html")).build()))
|
||||
.version("1.0.0")
|
||||
.build();
|
||||
|
||||
let redoc = Redoc::with_url("/docs/", api.clone());
|
||||
let swagger = SwaggerUi::new("/docs2/")
|
||||
.url("/docs2/openapi.json", api)
|
||||
.config(Config::default()
|
||||
.try_it_out_enabled(true)
|
||||
);
|
||||
|
||||
let router = router.merge(redoc);
|
||||
let router = router.merge(swagger);
|
||||
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, router).await.unwrap();
|
||||
}
|
||||
|
||||
|
|
|
|||
Reference in a new issue