97 lines
2.7 KiB
Rust
97 lines
2.7 KiB
Rust
use actix_web::{App, HttpServer};
|
|
use sqlx::postgres::PgPoolOptions;
|
|
use sqlx::{migrate, PgPool};
|
|
|
|
/// ActivityPub stuff.
|
|
mod ap;
|
|
|
|
mod conf;
|
|
|
|
/// Core data types used throughout the entire app.
|
|
mod core;
|
|
|
|
/// Data sources for repositories.
|
|
///
|
|
/// Data sources are the interfaces between repositories and an underlying
|
|
/// storage layer, such as Postgres or Redis. Each data source is only
|
|
/// responsible for a single storage engine, and a repository may have multiple
|
|
/// data sources of different preferences.
|
|
mod data;
|
|
|
|
/// JSON entities for the REST API.
|
|
mod ent;
|
|
|
|
/// Asynchronous background workers.
|
|
mod job;
|
|
|
|
/// Middleware for request handlers.
|
|
mod middle;
|
|
|
|
/// Database models and validation.
|
|
mod model;
|
|
|
|
/// The central interface between data storage and the rest of the app.
|
|
///
|
|
/// This module contains all _Repositories_, which are the central interface
|
|
/// between the data storage/management code and the rest of the server.
|
|
/// They act as a full layer of abstraction to keep the rest of the app
|
|
/// completely agnostic to the internals of how storage, including caching,
|
|
/// is implemented.
|
|
///
|
|
/// Any data that the rest of the app needs access to or wishes to store must
|
|
/// travel through an interface provided by a repository. This makes them
|
|
/// perfect gatekeepers for enforcing validation, which is why APIs that store
|
|
/// data will typically be implemented as generics that require an
|
|
/// `Into<Sane<T>>` (where `T` is the model structure for that database table).
|
|
///
|
|
/// Internally, repositories act on several _Data Sources_.
|
|
/// See the [`data`] module for more information.
|
|
mod repo;
|
|
|
|
/// HTTP request handlers.
|
|
mod route;
|
|
|
|
mod state;
|
|
|
|
/// Miscellaneous little helpers.
|
|
mod util;
|
|
|
|
use crate::core::*;
|
|
use conf::Config;
|
|
|
|
#[actix_web::main]
|
|
async fn main() -> std::io::Result<()> {
|
|
dotenvy::dotenv().ok();
|
|
pretty_env_logger::init();
|
|
|
|
let config = Config::from_env();
|
|
info!("Establishing database connection");
|
|
let db_pool = init_db(&config).await.unwrap();
|
|
let bind_params = (config.bind_addr.clone(), config.bind_port.clone());
|
|
let state = state::new(config, db_pool);
|
|
|
|
info!("Starting application");
|
|
HttpServer::new(move || {
|
|
App::new()
|
|
.wrap(actix_web::middleware::DefaultHeaders::new().add(("Server", "nyano")))
|
|
.wrap(middle::auth::Auth::new(state.clone()))
|
|
.app_data(state.clone())
|
|
.configure(route::configure)
|
|
})
|
|
.bind(bind_params)?
|
|
.run()
|
|
.await
|
|
}
|
|
|
|
async fn init_db(conf: &Config) -> sqlx::Result<PgPool> {
|
|
let pool = PgPoolOptions::new()
|
|
.max_connections(5)
|
|
.connect(&conf.database_url)
|
|
.await?;
|
|
|
|
info!("Running migrations");
|
|
migrate!().run(&pool).await?;
|
|
|
|
Ok(pool)
|
|
}
|