chore: stage remaining scaffolding

This commit is contained in:
m00d 2025-10-01 12:53:20 +02:00
parent 5a8823fddb
commit 4d0aa78dbd
11 changed files with 696 additions and 0 deletions

80
src/bin/graphql_server.rs Normal file
View file

@ -0,0 +1,80 @@
#![cfg(feature = "graphql")]
use std::env;
use std::sync::Arc;
use actix_web::{App, HttpRequest, HttpResponse, HttpServer, middleware::Compress, web};
use anyhow::{Context, Result};
use juniper_actix::{graphiql_handler, graphql_handler};
use package_management::db;
use package_management::graphql::{self, GraphQLContext, Schema};
const DEFAULT_BIND_ADDR: &str = "127.0.0.1:8080";
#[actix_web::main]
async fn main() -> std::io::Result<()> {
if let Err(err) = run().await {
eprintln!("GraphQL server failed: {err:#}");
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
err.to_string(),
));
}
Ok(())
}
async fn run() -> Result<()> {
let pool = db::establish_pool().context("initialising SQLite pool")?;
let schema = Arc::new(graphql::create_schema());
let jokes = Arc::new(graphql::context::JokeCatalog::default());
let bind_addr = env::var("LPKG_GRAPHQL_ADDR").unwrap_or_else(|_| DEFAULT_BIND_ADDR.to_string());
let workers = worker_count();
println!("GraphQL server listening on {bind_addr} with {workers} worker(s)");
HttpServer::new(move || {
let app_schema = Arc::clone(&schema);
let pool = pool.clone();
let jokes = Arc::clone(&jokes);
App::new()
.app_data(web::Data::from(app_schema))
.app_data(web::Data::new(pool))
.app_data(web::Data::from(jokes))
.wrap(Compress::default())
.service(
web::resource("/graphql")
.route(web::post().to(graphql_endpoint))
.route(web::get().to(graphql_endpoint)),
)
.service(web::resource("/playground").route(web::get().to(graphiql_endpoint)))
})
.workers(workers)
.bind(&bind_addr)
.with_context(|| format!("binding GraphQL server to {bind_addr}"))?
.run()
.await
.context("running GraphQL server")
}
async fn graphql_endpoint(
schema: web::Data<Arc<Schema>>,
pool: web::Data<db::Pool>,
jokes: web::Data<Arc<graphql::context::JokeCatalog>>,
req: HttpRequest,
payload: web::Payload,
) -> Result<HttpResponse, actix_web::Error> {
let context = GraphQLContext::with_catalog(pool.get_ref().clone(), Arc::clone(jokes.get_ref()));
graphql_handler(schema.get_ref().as_ref(), &context, req, payload).await
}
async fn graphiql_endpoint() -> Result<HttpResponse, actix_web::Error> {
graphiql_handler("/graphql", None).await
}
fn worker_count() -> usize {
let suggested = num_cpus::get();
suggested.clamp(1, 8)
}