pub mod schema;
pub mod types;
use async_graphql::Schema;
use async_graphql_axum::{GraphQLRequest, GraphQLResponse};
use axum::{
extract::State,
response::{Html, IntoResponse},
routing::get,
Router,
};
use crate::AppContext;
use schema::{MutationRoot, QueryRoot, SubscriptionRoot};
pub type ApiSchema = Schema<QueryRoot, MutationRoot, SubscriptionRoot>;
#[must_use]
pub fn build_schema(ctx: AppContext) -> ApiSchema {
Schema::build(QueryRoot, MutationRoot, SubscriptionRoot)
.data(ctx)
.finish()
}
#[must_use]
pub fn create_router(ctx: AppContext) -> Router<AppContext> {
let schema = build_schema(ctx.clone());
Router::new()
.route("/", get(graphql_playground).post(graphql_handler))
.with_state(schema)
}
async fn graphql_handler(State(schema): State<ApiSchema>, req: GraphQLRequest) -> GraphQLResponse {
schema.execute(req.into_inner()).await.into()
}
#[allow(clippy::unused_async)]
async fn graphql_playground() -> impl IntoResponse {
Html(PLAYGROUND_HTML)
}
const PLAYGROUND_HTML: &str = r#"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>7sense GraphQL Playground</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.26/build/static/css/index.css" />
<script src="https://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.26/build/static/js/middleware.js"></script>
</head>
<body>
<div id="root"></div>
<script>
window.addEventListener('load', function (event) {
GraphQLPlayground.init(document.getElementById('root'), {
endpoint: '/graphql',
settings: {
'editor.theme': 'dark',
'editor.fontSize': 14,
'request.credentials': 'include',
},
tabs: [
{
name: 'Example Queries',
endpoint: '/graphql',
query: `# 7sense GraphQL API
# Get all clusters
query ListClusters {
clusters {
id
label
size
density
}
}
# Find similar segments
query FindNeighbors($segmentId: UUID!, $k: Int) {
neighbors(segmentId: $segmentId, k: $k) {
segmentId
similarity
startTime
endTime
}
}
`
}
]
});
});
</script>
</body>
</html>
"#;
#[cfg(test)]
mod tests {
use super::*;
}