lightweight com.atproto.sync.listReposByCollection
at main 76 lines 2.3 kB view raw
1//! XRPC API server. 2//! 3//! Serves XRPC endpoints via axum routers built with `jacquard-axum`'s 4//! `IntoRouter` helper. 5 6mod admin; 7mod get_repo_status; 8mod hello; 9mod list_repos; 10mod list_repos_by_collection; 11 12use admin::admin_status; 13use get_repo_status::get_repo_status; 14use list_repos::list_repos; 15use list_repos_by_collection::list_repos_by_collection; 16 17use std::net::SocketAddr; 18 19use jacquard_common::url::Host; 20 21use crate::com_atproto::sync::list_repos_by_collection::ListReposByCollectionRequest; 22use jacquard_api::com_atproto::sync::{ 23 get_repo_status::GetRepoStatusRequest, list_repos::ListReposRequest, 24}; 25use jacquard_axum::IntoRouter; 26 27use crate::error::Result; 28use crate::storage::DbRef; 29 30/// Config for the admin endpoints. Only constructed when `--admin-password` is 31/// set; when absent the `/admin/*` routes are not registered at all. 32#[derive(Clone)] 33pub struct AdminConfig { 34 /// The relay/PDS host that lightrail is subscribed to and backfilling from. 35 pub subscribe_host: Host, 36 /// Required Bearer token for all admin endpoints. 37 pub admin_password: String, 38} 39 40/// Build and serve the axum application on `addr`. 41/// 42/// Routes always registered: 43/// GET /xrpc/com.atproto.sync.getRepoStatus 44/// GET /xrpc/com.atproto.sync.listRepos 45/// GET /xrpc/com.atproto.sync.listReposByCollection 46/// 47/// Registered only when `admin_config` is `Some`: 48/// GET /admin/status 49pub async fn serve( 50 addr: SocketAddr, 51 db: DbRef, 52 token: tokio_util::sync::CancellationToken, 53 admin_config: Option<AdminConfig>, 54) -> Result<()> { 55 let base = GetRepoStatusRequest::into_router(get_repo_status) 56 .merge(ListReposRequest::into_router(list_repos)) 57 .merge(ListReposByCollectionRequest::into_router( 58 list_repos_by_collection, 59 )); 60 61 let app = if let Some(config) = admin_config { 62 base.route("/admin/status", axum::routing::get(admin_status)) 63 .route("/", axum::routing::get(hello::hello)) 64 .with_state(db) 65 .layer(axum::Extension(config)) 66 } else { 67 base.route("/", axum::routing::get(hello::hello)) 68 .with_state(db) 69 }; 70 71 let listener = tokio::net::TcpListener::bind(addr).await?; 72 axum::serve(listener, app) 73 .with_graceful_shutdown(token.cancelled_owned()) 74 .await?; 75 Ok(()) 76}