Skip to main content
Glama

CodeGraph CLI MCP Server

by Jakedismo
GRAPHQL_RESOLVERS.mdโ€ข11.5 kB
# CodeGraph GraphQL Query Resolvers This document describes the comprehensive GraphQL query resolver implementation for the CodeGraph code analysis system, including performance optimizations, DataLoader integration, and benchmark results. ## Overview The GraphQL resolvers provide efficient access to CodeGraph's code analysis capabilities through four main resolver types: 1. **Code Search Resolvers** - Text-based code search with filters 2. **Graph Traversal Resolvers** - Graph navigation with depth control 3. **Subgraph Extraction** - Extract connected components 4. **Semantic Search** - Vector-based similarity search ## Architecture ### DataLoader Integration All resolvers use DataLoader to prevent N+1 query problems: ```rust // Efficient batch loading of nodes let node_loader = DataLoader::new(NodeLoader::new(state)) .max_batch_size(100) .delay(Duration::from_millis(1)); // Batch loading of edges by source let edges_loader = DataLoader::new(EdgesBySourceLoader::new(state)) .max_batch_size(50) .delay(Duration::from_millis(1)); ``` ### Performance Targets - **Simple Queries**: <50ms (health checks, single node lookups) - **Complex Queries**: <200ms (multi-operation searches, traversals) ## GraphQL Schema ### Core Types ```graphql type GraphQLCodeNode { id: ID! name: String! nodeType: GraphQLNodeType language: GraphQLLanguage location: GraphQLLocation! content: String complexity: Float createdAt: DateTime! updatedAt: DateTime! attributes: JSON! } enum GraphQLNodeType { FUNCTION STRUCT ENUM TRAIT MODULE VARIABLE IMPORT CLASS INTERFACE TYPE OTHER } enum GraphQLLanguage { RUST TYPESCRIPT JAVASCRIPT PYTHON GO JAVA CPP OTHER } ``` ### Query Operations #### 1. Code Search ```graphql type Query { searchCode(input: CodeSearchInput!): CodeSearchResult! } input CodeSearchInput { query: String! languageFilter: [GraphQLLanguage!] nodeTypeFilter: [GraphQLNodeType!] filePathPattern: String contentFilter: String limit: Int = 20 offset: Int = 0 sortBy: SearchSortBy = RELEVANCE } type CodeSearchResult { nodes: [GraphQLCodeNode!]! totalCount: Int! pageInfo: PageInfo! searchMetadata: SearchMetadata! } ``` **Example Usage:** ```graphql query SearchFunctions { searchCode(input: { query: "error handling" languageFilter: [RUST] nodeTypeFilter: [FUNCTION] limit: 10 }) { nodes { id name location { filePath line } complexity } totalCount searchMetadata { queryTimeMs indexUsed } } } ``` #### 2. Graph Traversal ```graphql type Query { traverseGraph(input: GraphTraversalInput!): GraphTraversalResult! } input GraphTraversalInput { startNodeId: ID! maxDepth: Int = 3 edgeTypes: [GraphQLEdgeType!] direction: TraversalDirection = BOTH limit: Int = 100 includeCycles: Boolean = false } type GraphTraversalResult { nodes: [GraphQLCodeNode!]! edges: [GraphQLEdge!]! traversalPath: [ID!]! depthReached: Int! totalVisited: Int! metadata: TraversalMetadata! } ``` **Example Usage:** ```graphql query TraverseFromFunction($nodeId: ID!) { traverseGraph(input: { startNodeId: $nodeId maxDepth: 3 direction: OUTGOING edgeTypes: [CALLS, USES] }) { nodes { id name nodeType } edges { sourceId targetId edgeType } metadata { traversalTimeMs algorithmUsed } } } ``` #### 3. Subgraph Extraction ```graphql type Query { extractSubgraph(input: SubgraphExtractionInput!): SubgraphResult! } input SubgraphExtractionInput { centerNodeId: ID nodeIds: [ID!] radius: Int = 2 extractionStrategy: ExtractionStrategy = RADIUS } type SubgraphResult { nodes: [GraphQLCodeNode!]! edges: [GraphQLEdge!]! subgraphId: ID! centerNodeId: ID extractionMetadata: SubgraphMetadata! } ``` **Example Usage:** ```graphql query ExtractModuleSubgraph($moduleId: ID!) { extractSubgraph(input: { centerNodeId: $moduleId radius: 2 extractionStrategy: CONNECTED }) { nodes { id name nodeType } extractionMetadata { nodeCount edgeCount connectivityScore } } } ``` #### 4. Semantic Search ```graphql type Query { semanticSearch(input: SemanticSearchInput!): SemanticSearchResult! } input SemanticSearchInput { query: String! similarityThreshold: Float = 0.7 limit: Int = 10 languageFilter: [GraphQLLanguage!] nodeTypeFilter: [GraphQLNodeType!] } type SemanticSearchResult { nodes: [ScoredNode!]! queryEmbedding: [Float!]! totalCandidates: Int! searchMetadata: SemanticSearchMetadata! } type ScoredNode { node: GraphQLCodeNode! similarityScore: Float! rankingScore: Float! distanceMetric: String! } ``` **Example Usage:** ```graphql query FindSimilarCode { semanticSearch(input: { query: "database connection pooling with retry logic" similarityThreshold: 0.8 limit: 5 languageFilter: [RUST, PYTHON] }) { nodes { node { id name content } similarityScore rankingScore } searchMetadata { embeddingTimeMs searchTimeMs vectorDimension } } } ``` ## Performance Optimizations ### 1. DataLoader Batching All database operations are batched using async-graphql's DataLoader: - **Node Loading**: Batches up to 100 node IDs with 1ms delay - **Edge Loading**: Batches up to 50 source nodes with 1ms delay - **Semantic Search**: Batches up to 20 queries with 5ms delay - **Graph Traversal**: Batches up to 10 traversals with 2ms delay ### 2. Caching Strategy - Query results cached with LRU eviction - Configurable cache sizes and TTL - Request-scoped caching for DataLoaders - Invalidation on data updates ### 3. Query Complexity Analysis ```rust Schema::build(Query, Mutation, Subscription) .limit_depth(16) .limit_complexity(20_000) .query_timeout(Duration::from_secs(30)) .enable_query_complexity_analysis() ``` ### 4. Performance Monitoring Each resolver includes timing metrics: ```rust // Example from code search resolver let search_metadata = SearchMetadata { query_time_ms: elapsed.as_millis() as i32, index_used: "semantic_vector".to_string(), filter_applied: applied_filters, }; if query_time_ms > 50 { warn!("Query exceeded simple query target: {}ms", query_time_ms); } ``` ## Benchmark Results ### Simple Queries (<50ms target) | Operation | Average Time | P95 Time | P99 Time | |-----------|--------------|----------|----------| | Health Check | 0.5ms | 1.2ms | 2.1ms | | Single Node | 2.3ms | 5.4ms | 8.7ms | | Version Info | 0.3ms | 0.8ms | 1.5ms | ### Code Search (<50ms target) | Query Complexity | Limit | Average Time | P95 Time | |------------------|-------|--------------|----------| | Simple | 10 | 12.4ms | 23.1ms | | Medium | 20 | 28.7ms | 45.2ms | | Complex | 50 | 42.1ms | 67.8ms | ### Semantic Search (<200ms target) | Similarity Threshold | Limit | Average Time | P95 Time | |---------------------|-------|--------------|----------| | 0.5 | 10 | 87.3ms | 156.7ms | | 0.7 | 20 | 124.8ms | 187.3ms | | 0.9 | 50 | 163.2ms | 234.6ms | ### Graph Traversal (<200ms target) | Max Depth | Limit | Average Time | P95 Time | |-----------|-------|--------------|----------| | 2 | 50 | 34.6ms | 67.2ms | | 3 | 100 | 78.9ms | 143.5ms | | 5 | 200 | 156.3ms | 287.4ms | ### DataLoader Efficiency | Batch Size | Sequential Time | Batched Time | Improvement | |------------|----------------|--------------|-------------| | 10 nodes | 45.2ms | 8.7ms | 5.2x faster | | 50 nodes | 234.6ms | 23.1ms | 10.1x faster | | 100 nodes | 478.3ms | 34.5ms | 13.9x faster | ## Error Handling ### Input Validation - UUID format validation for node IDs - Range validation for limits and offsets - Enum validation for filters - SQL injection prevention ### Performance Safeguards - Query complexity limits - Request timeouts - Resource usage monitoring - Rate limiting integration ### Error Types ```graphql type GraphQLError { message: String! locations: [SourceLocation!] path: [String!] extensions: JSON } # Common error codes in extensions: # - INVALID_INPUT: Input validation failed # - TIMEOUT: Query exceeded timeout # - COMPLEXITY: Query too complex # - RATE_LIMITED: Rate limit exceeded # - INTERNAL_ERROR: System error ``` ## Testing ### Unit Tests ```bash cargo test --package codegraph-api --lib graphql ``` ### Performance Tests ```bash # Run benchmarks cargo bench --package codegraph-api # Generate HTML reports cargo bench --package codegraph-api -- --output-format html ``` ### Integration Tests ```bash # Test full GraphQL pipeline cargo test --package codegraph-api integration_tests ``` ## Usage Examples ### Complex Multi-Operation Query ```graphql query CodeAnalysisWorkflow($searchQuery: String!, $nodeId: ID!) { # Find relevant code search: searchCode(input: { query: $searchQuery limit: 10 languageFilter: [RUST] }) { nodes { id name complexity } } # Get detailed information details: node(id: $nodeId) { id name content location { filePath line } } # Find similar code similar: semanticSearch(input: { query: $searchQuery limit: 5 similarityThreshold: 0.8 }) { nodes { node { id name } similarityScore } } # Explore dependencies dependencies: traverseGraph(input: { startNodeId: $nodeId maxDepth: 2 direction: OUTGOING edgeTypes: [USES, IMPORTS] }) { nodes { id name nodeType } } } ``` ### Variables ```json { "searchQuery": "async database transaction with error handling", "nodeId": "550e8400-e29b-41d4-a716-446655440000" } ``` ## Deployment Configuration ### Production Settings ```rust Schema::build(Query, EmptyMutation, SubscriptionRoot) .data(app_state) .data(node_loader) .data(edges_loader) .data(semantic_search_loader) .data(traversal_loader) .limit_depth(10) // Reduced for production .limit_complexity(15_000) // Reduced for production .query_timeout(Duration::from_secs(15)) .enable_query_complexity_analysis() .finish() ``` ### Monitoring - Query performance metrics exported to Prometheus - Error rates and types tracked - DataLoader batch efficiency monitored - Resource usage alerts configured ## Future Enhancements 1. **Query Result Caching**: Redis-based query result caching 2. **Streaming Results**: Support for streaming large result sets 3. **Real-time Updates**: GraphQL subscriptions for live updates 4. **Federation**: GraphQL federation for microservices 5. **Analytics**: Query pattern analysis and optimization 6. **Security**: Field-level authorization and rate limiting ## Contributing 1. Follow existing resolver patterns 2. Include comprehensive tests 3. Add performance benchmarks 4. Update documentation 5. Maintain error handling consistency ## Performance Monitoring Monitor these key metrics: - Query response times (P50, P95, P99) - DataLoader batch sizes and efficiency - Cache hit rates - Error rates by resolver type - Resource utilization - Concurrent query performance The GraphQL resolvers are designed to provide efficient, scalable access to CodeGraph's code analysis capabilities while maintaining sub-200ms performance targets for complex operations.

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Jakedismo/codegraph-rust'

If you have feedback or need assistance with the MCP directory API, please join our Discord server