Getting Started
Overview
graph-api
is an API that helps you work with graphs in Rust. Graphs are powerful data structures used to represent
relationships between entities. With the Graph API, you can create, manipulate, and traverse graphs with ease.
Any implementation of the Graph trait will benefit from an ergonomic walker API that allows you to perform complex
traversals. For the purposes of this documentation, we will use SimpleGraph
, but you may choose any other graph
implementation.
Basic Concepts
A graph consists of:
- Vertices (also called nodes): These represent entities in your data model
- Edges (also called links or connections): These represent relationships between entities
- Properties: Both vertices and edges can have properties that store data
The Graph API provides:
- A common interface for working with graph data
- Powerful traversal capabilities with the Walker API
- Index support for efficient lookups
- Derive macros for easy model definition
Installation
Add the Graph API to your project dependencies:
[dependencies]
graph-api-lib = "0.2.0"
graph-api-derive = "0.1.4" # For derive macros
For a simple graph implementation:
[dependencies]
graph-api-simplegraph = "0.2.1"
Examples
Your First Graph
Let's define a simple graph model with people and projects:
// Define our vertex types using derive macro
#[derive(Debug, Clone, VertexExt)]
enum Vertex {
// A person vertex with name and age properties
Person {
name: String,
#[index(hash)]
username: String,
age: u8,
},
// A project vertex with just a name
Project {
name: String,
},
}
// Define our edge types using derive macro
#[derive(Debug, Clone, EdgeExt)]
enum Edge {
// Simple relationship types
Knows,
Created,
WorksOn,
}
Now we can create a graph and add some data:
// Create a new empty graph
let mut graph = SimpleGraph::<Vertex, Edge>::new();
// Add vertices
let alice = graph.add_vertex(Vertex::Person {
name: "Alice".to_string(),
username: "alice123".to_string(),
age: 30,
});
let bob = graph.add_vertex(Vertex::Person {
name: "Bob".to_string(),
username: "bob456".to_string(),
age: 28,
});
let project = graph.add_vertex(Vertex::Project {
name: "Graph API".to_string(),
});
// Connect vertices with edges
graph.add_edge(alice, bob, Edge::Knows);
graph.add_edge(alice, project, Edge::Created);
graph.add_edge(bob, project, Edge::WorksOn);
And finally, we can query the graph:
// Find all people who created a project
let creators = graph
.walk()
.vertices(VertexSearch::scan())
.filter_person() // Type-safe filter using generated helper
.edges(Edge::created()) // Using generated search function
.head()
.filter_project() // Type-safe filter using generated helper
.map(|v, _| {
// Use projection for type-safe property access
v.project::<Project<_>>().unwrap().name().to_string()
})
.collect::<Vec<_>>();
// Find all people who know someone
let people_with_friends = graph
.walk()
.vertices(VertexSearch::scan())
.filter_person() // Type-safe filter using generated helper
.edges(Edge::knows()) // Using generated search function
.tail()
.filter_person() // Type-safe filter using generated helper
.map(|v, _| {
// Use projection for type-safe property access
v.project::<Person<_>>().unwrap().name().to_string()
})
.collect::<Vec<_>>();
Advanced Usage
Graph API supports more advanced features that we'll explore in later sections:
- Complex traversals with the Walker API
- Different index types for optimized queries
- Transaction support (with appropriate graph implementations)
- Custom property types
Next Steps
Now that you have created your first graph, you can:
- Learn about defining a model for your graph data
- Explore basic operations for working with graphs
- Discover graph traversal techniques using walkers