diff --git a/radicle-httpd/src/api.rs b/radicle-httpd/src/api.rs index 8650460e..b06dd8cd 100644 --- a/radicle-httpd/src/api.rs +++ b/radicle-httpd/src/api.rs @@ -121,6 +121,11 @@ async fn root_handler(Extension(ctx): Extension) -> impl IntoResponse { "href": "/v1/delegates/:did/projects", "rel": "projects", "type": "GET" + }, + { + "href": "/v1/stats", + "rel": "stats", + "type": "GET" } ] }); diff --git a/radicle-httpd/src/api/v1.rs b/radicle-httpd/src/api/v1.rs index 543d4dc4..97829cdf 100644 --- a/radicle-httpd/src/api/v1.rs +++ b/radicle-httpd/src/api/v1.rs @@ -2,6 +2,7 @@ mod delegates; mod node; mod projects; mod sessions; +mod stats; use axum::Router; @@ -12,7 +13,8 @@ pub fn router(ctx: Context) -> Router { .merge(node::router(ctx.clone())) .merge(sessions::router(ctx.clone())) .merge(delegates::router(ctx.clone())) - .merge(projects::router(ctx)); + .merge(projects::router(ctx.clone())) + .merge(stats::router(ctx)); Router::new().nest("/v1", routes) } diff --git a/radicle-httpd/src/api/v1/stats.rs b/radicle-httpd/src/api/v1/stats.rs new file mode 100644 index 00000000..fdb51278 --- /dev/null +++ b/radicle-httpd/src/api/v1/stats.rs @@ -0,0 +1,24 @@ +use axum::response::IntoResponse; +use axum::routing::get; +use axum::{Extension, Json, Router}; +use serde_json::json; + +use crate::api::error::Error; +use crate::api::Context; + +pub fn router(ctx: Context) -> Router { + Router::new() + .route("/stats", get(stats_handler)) + .layer(Extension(ctx)) +} + +/// Return the stats for the node. +/// `GET /stats` +async fn stats_handler(Extension(ctx): Extension) -> impl IntoResponse { + let storage = &ctx.profile.storage; + let projects = storage.projects()?.len(); + + Ok::<_, Error>(Json( + json!({ "projects": { "count": projects }, "users": { "count": 0 } }), + )) +}