3.0 KiB
Graph API
Status: Draft (2025-11-26) — aligns with Sprint 0207 Graph API implementation (in-memory seed; RBAC + budgets enforced).
Base URL: <gateway>/api/graph (examples use relative paths).
Common headers
X-Stella-Tenant(required)Authorization: Bearer <token>(required)X-Stella-Scopes: space/comma/semicolon separated scopes/graph/search:graph:readorgraph:query/graph/query|paths|diff:graph:query/graph/export:graph:exportContent-Type for requests:application/jsonStreaming responses:application/x-ndjson
POST /graph/search
Returns NDJSON stream of tiles (node, optional cursor).
Body:
{
"kinds": ["component", "artifact"],
"query": "pkg:npm/",
"filters": { "ecosystem": "npm" },
"limit": 50,
"cursor": "opaque"
}
Errors:
- 400
GRAPH_VALIDATION_FAILED(missing kinds/query/filters) - 401 missing auth; 403 missing scopes
POST /graph/query
Streams nodes, edges (optional), stats, cursor with cost metadata.
Body:
{
"kinds": ["component"],
"query": "widget",
"filters": { "tenant": "acme" },
"includeEdges": true,
"includeStats": true,
"includeOverlays": true,
"limit": 100,
"cursor": "opaque",
"budget": { "tiles": 6000, "nodes": 5000, "edges": 10000 }
}
Error tile if edge budget exceeded: { "type":"error","data":{"error":"GRAPH_BUDGET_EXCEEDED",...}}
POST /graph/paths
Finds paths up to depth 6 between sources/targets.
Body:
{
"sources": ["gn:acme:component:one"],
"targets": ["gn:acme:component:two"],
"kinds": ["depends_on"],
"maxDepth": 4,
"includeOverlays": false,
"budget": { "tiles": 2000, "nodes": 1500, "edges": 3000 }
}
Response: NDJSON tiles (node, edge, stats, cursor).
POST /graph/diff
Diff two snapshots.
Body:
{
"snapshotA": "snapA",
"snapshotB": "snapB",
"includeEdges": true,
"includeStats": true,
"budget": { "tiles": 2000 }
}
Response tiles: node/edge with change types, stats, optional cursor.
POST /graph/export
Kicks off an in-memory export job and returns manifest.
Body:
{
"format": "ndjson", // ndjson|csv|graphml|png|svg
"includeEdges": true,
"snapshotId": "snapA", // optional
"kinds": ["component"], // optional
"query": "pkg:", // optional
"filters": { "ecosystem": "npm" }
}
Response:
{
"jobId": "job-123",
"status": "completed",
"format": "ndjson",
"sha256": "...",
"size": 1234,
"downloadUrl": "/graph/export/job-123",
"completedAt": "2025-11-26T00:00:00Z"
}
Download: GET /graph/export/{jobId} (returns file, headers include X-Content-SHA256).
Health
GET /healthz → 200 when service is ready; no auth/scopes required.
Error envelope
{ "error": "GRAPH_VALIDATION_FAILED", "message": "details", "requestId": "optional" }
Notes
- All timestamps UTC ISO-8601.
- Ordering is deterministic; cursors are opaque base64 offsets.
- Overlays use
policy.overlay.v1andopenvex.v1payloads. Budgeted tiles reserve room for cursors whenhasMoreis true.