use axum::{
extract::{Query, State},
Json,
};
use serde::{Deserialize, Serialize};
use crate::error::Result;
use crate::middleware::RequestNamespace;
use crate::rest::triples::{TripleDto, ValueDto};
use crate::state::AppState;
#[cfg_attr(feature = "mcp", derive(schemars::JsonSchema))]
#[derive(Debug, Deserialize)]
pub struct PatternQueryRequest {
pub subject: Option<String>,
pub predicate: Option<String>,
pub object: Option<ValueDto>,
#[serde(default = "default_limit")]
pub limit: usize,
}
fn default_limit() -> usize {
100
}
#[cfg_attr(feature = "mcp", derive(schemars::JsonSchema))]
#[derive(Debug, Serialize)]
pub struct PatternQueryResponse {
pub matches: Vec<TripleDto>,
pub total: usize,
pub pattern: PatternDescription,
}
#[cfg_attr(feature = "mcp", derive(schemars::JsonSchema))]
#[derive(Debug, Serialize)]
pub struct PatternDescription {
pub subject: Option<String>,
pub predicate: Option<String>,
pub object: Option<serde_json::Value>,
}
pub async fn query_pattern(
State(state): State<AppState>,
ns_ext: Option<axum::Extension<RequestNamespace>>,
Json(req): Json<PatternQueryRequest>,
) -> Result<Json<PatternQueryResponse>> {
let namespace = ns_ext.and_then(|axum::Extension(RequestNamespace(ns))| ns);
Ok(Json(
crate::service::query::query_pattern(&state, req, namespace).await?,
))
}
#[cfg_attr(feature = "mcp", derive(schemars::JsonSchema))]
#[derive(Debug, Deserialize)]
pub struct ListSubjectsQuery {
pub predicate: Option<String>,
#[serde(default = "default_limit")]
pub limit: usize,
}
pub async fn list_subjects(
State(state): State<AppState>,
ns_ext: Option<axum::Extension<RequestNamespace>>,
Query(query): Query<ListSubjectsQuery>,
) -> Result<Json<ListSubjectsResponse>> {
let namespace = ns_ext.and_then(|axum::Extension(RequestNamespace(ns))| ns);
Ok(Json(
crate::service::query::list_subjects(&state, query, namespace).await?,
))
}
#[cfg_attr(feature = "mcp", derive(schemars::JsonSchema))]
#[derive(Debug, Serialize)]
pub struct ListSubjectsResponse {
pub subjects: Vec<String>,
pub total: usize,
}
#[cfg_attr(feature = "mcp", derive(schemars::JsonSchema))]
#[derive(Debug, Deserialize)]
pub struct ListPredicatesQuery {
pub subject: Option<String>,
#[serde(default = "default_limit")]
pub limit: usize,
}
pub async fn list_predicates(
State(state): State<AppState>,
ns_ext: Option<axum::Extension<RequestNamespace>>,
Query(query): Query<ListPredicatesQuery>,
) -> Result<Json<ListPredicatesResponse>> {
let namespace = ns_ext.and_then(|axum::Extension(RequestNamespace(ns))| ns);
Ok(Json(
crate::service::query::list_predicates(&state, query, namespace).await?,
))
}
#[cfg_attr(feature = "mcp", derive(schemars::JsonSchema))]
#[derive(Debug, Serialize)]
pub struct ListPredicatesResponse {
pub predicates: Vec<String>,
pub total: usize,
}