Data Adapters
Connect to data sources with client-side adapters for static data, REST APIs, and custom backends.
Data Adapters
InferaGraph is framework-agnostic and makes no assumptions about where your data lives. The DataAdapter interface defines a contract for how applications provide data to InferaGraph -- whether from a static file, a REST API, a GraphQL endpoint, or a database.
The DataAdapter Interface
Seven methods that cover the full data lifecycle: initial load, node expansion, pathfinding, search, filtering, and content retrieval. All methods are async and return Promises.
interface DataAdapter {
// Called once on mount — return the initial visible graph
getInitialView(config?: DataAdapterConfig): Promise<GraphData>;
// Load a single node by ID
getNode(id: string): Promise<Node | undefined>;
// Expand: fetch neighbors within N hops
getNeighbors(id: string, depth?: number): Promise<GraphData>;
// Pathfinding between two nodes
findPath(fromId: string, toId: string): Promise<GraphData>;
// Full-text search with pagination
search(query: string, page?: PageToken): Promise<SearchResult>;
// Attribute-based filtering with pagination
filter(filter: FilterCriteria, page?: PageToken): Promise<SearchResult>;
// Rich content for detail panels (optional)
getContent(id: string): Promise<NodeContent | undefined>;
}StaticDataAdapter
For small or static datasets, the built-in StaticDataAdapter wraps an in-memory graph and implements the full DataAdapter interface. Perfect for prototyping or apps where the entire graph fits in memory.
import { StaticDataAdapter } from '@inferagraph/core';
import { GraphProvider, InferaGraph } from '@inferagraph/react';
// Wrap a static dataset — great for prototyping or small graphs
const adapter = new StaticDataAdapter({
nodes: [
{ id: 'abraham', attributes: { name: 'Abraham', type: 'person' } },
{ id: 'sarah', attributes: { name: 'Sarah', type: 'person' } },
{ id: 'isaac', attributes: { name: 'Isaac', type: 'person' } },
],
edges: [
{ id: 'e1', sourceId: 'abraham', targetId: 'isaac',
attributes: { type: 'father_of' } },
{ id: 'e2', sourceId: 'sarah', targetId: 'isaac',
attributes: { type: 'mother_of' } },
{ id: 'e3', sourceId: 'abraham', targetId: 'sarah',
attributes: { type: 'husband_of' } },
],
});
function App() {
return (
<GraphProvider adapter={adapter}>
<InferaGraph />
</GraphProvider>
);
}Custom Adapter (REST API)
Implement a custom adapter to fetch data from any backend. Each method maps naturally to a REST endpoint, GraphQL query, or WebSocket message.
import type { DataAdapter } from '@inferagraph/core';
import { GraphProvider, InferaGraph } from '@inferagraph/react';
// Custom adapter: fetch from any REST API
const apiAdapter: DataAdapter = {
getInitialView: () =>
fetch('/api/graph').then(r => r.json()),
getNode: (id) =>
fetch(`/api/nodes/${id}`).then(r => r.json()),
getNeighbors: (id, depth) =>
fetch(`/api/graph/neighbors/${id}?depth=${depth}`).then(r => r.json()),
findPath: (from, to) =>
fetch(`/api/graph/path?from=${from}&to=${to}`).then(r => r.json()),
search: (q, page) =>
fetch(`/api/search?q=${q}&offset=${page?.offset ?? 0}`).then(r => r.json()),
filter: (f, page) =>
fetch('/api/filter', {
method: 'POST',
body: JSON.stringify({ filter: f, page }),
}).then(r => r.json()),
getContent: (id) =>
fetch(`/api/content/${id}`).then(r =>
r.ok ? r.json() : undefined
),
};
function App() {
return (
<GraphProvider adapter={apiAdapter}>
<InferaGraph />
</GraphProvider>
);
}Using GraphProvider with Adapters
GraphProvider accepts either a static data prop or a dynamic
adapter prop. Both work seamlessly with InferaGraph.
import { GraphProvider, InferaGraph } from '@inferagraph/react';
// Option 1: Static data (simple)
<GraphProvider data={patriarchsGraph}>
<InferaGraph />
</GraphProvider>
// Option 2: Dynamic adapter (REST, GraphQL, WebSocket, etc.)
<GraphProvider adapter={apiAdapter}>
<InferaGraph />
</GraphProvider>useInferaGraph with Adapters
When using an adapter, the useInferaGraph hook exposes additional
methods for on-demand data loading. The DataManager maintains an accumulating cache --
fetched data is merged into the local GraphStore, so repeated expansions never re-fetch nodes you already have.
import { useInferaGraph, InferaGraph } from '@inferagraph/react';
function GraphExplorer() {
const {
expandNode, // Fetch and merge neighbors for a node
findPath, // Find path between two nodes
search, // Full-text search via the adapter
getContent, // Load rich content for detail panels
isReady, // True once initial view is loaded
} = useInferaGraph();
const handleNodeClick = async (nodeId: string) => {
// Expand neighbors — e.g., click Abraham to see Isaac, Sarah
await expandNode(nodeId, 2);
// Load detail content
const content = await getContent(nodeId);
};
if (!isReady) return <Loading />;
return <InferaGraph onNodeClick={handleNodeClick} />;
}