feat: add basic graphql support

This commit is contained in:
2025-01-04 20:38:41 +08:00
parent caaa5dc0cc
commit 40cbf86f0f
62 changed files with 4053 additions and 675 deletions

View File

@@ -0,0 +1,7 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AppGraphQLConfig {
pub depth_limit: Option<usize>,
pub complexity_limit: Option<usize>,
}

View File

@@ -0,0 +1,5 @@
pub mod query_root;
pub mod service;
pub mod config;
pub use query_root::schema;

View File

@@ -0,0 +1,53 @@
use async_graphql::dynamic::*;
use sea_orm::DatabaseConnection;
use seaography::{Builder, BuilderContext};
lazy_static::lazy_static! { static ref CONTEXT : BuilderContext = BuilderContext :: default () ; }
pub fn schema(
database: DatabaseConnection,
depth: Option<usize>,
complexity: Option<usize>,
) -> Result<Schema, SchemaError> {
use crate::models::*;
let mut builder = Builder::new(&CONTEXT, database.clone());
seaography::register_entities!(
builder,
[
auth,
bangumi,
downloaders,
downloads,
episodes,
subscribers,
subscription_bangumi,
subscription_episode,
subscriptions
]
);
{
builder.register_enumeration::<auth::AuthType>();
builder.register_enumeration::<downloads::DownloadStatus>();
builder.register_enumeration::<subscriptions::SubscriptionCategory>();
builder.register_enumeration::<downloaders::DownloaderCategory>();
builder.register_enumeration::<downloads::DownloadMime>();
}
let schema = builder.schema_builder();
let schema = if let Some(depth) = depth {
schema.limit_depth(depth)
} else {
schema
};
let schema = if let Some(complexity) = complexity {
schema.limit_complexity(complexity)
} else {
schema
};
schema
.data(database)
.finish()
.inspect_err(|e| tracing::error!(e = ?e))
}

View File

@@ -0,0 +1,51 @@
use async_graphql::dynamic::{Schema, SchemaError};
use async_trait::async_trait;
use loco_rs::app::{AppContext, Initializer};
use once_cell::sync::OnceCell;
use sea_orm::DatabaseConnection;
use super::{config::AppGraphQLConfig, query_root};
use crate::config::AppConfigExt;
static APP_GRAPHQL_SERVICE: OnceCell<AppGraphQLService> = OnceCell::new();
#[derive(Debug)]
pub struct AppGraphQLService {
pub schema: Schema,
}
impl AppGraphQLService {
pub fn new(config: AppGraphQLConfig, db: DatabaseConnection) -> Result<Self, SchemaError> {
let schema = query_root::schema(db, config.depth_limit, config.complexity_limit)?;
Ok(Self { schema })
}
pub fn app_instance() -> &'static Self {
APP_GRAPHQL_SERVICE
.get()
.expect("AppGraphQLService is not initialized")
}
}
#[derive(Debug, Clone)]
pub struct AppGraphQLServiceInitializer;
#[async_trait]
impl Initializer for AppGraphQLServiceInitializer {
fn name(&self) -> String {
String::from("AppGraphQLServiceInitializer")
}
async fn before_run(&self, app_context: &AppContext) -> loco_rs::Result<()> {
APP_GRAPHQL_SERVICE.get_or_try_init(|| {
let config = app_context
.config
.get_app_conf()
.map_err(loco_rs::Error::wrap)?
.graphql;
let db = &app_context.db;
AppGraphQLService::new(config, db.clone()).map_err(loco_rs::Error::wrap)
})?;
Ok(())
}
}