graphbuff-server serves a DatabaseManager over HTTP/JSON, so any language can run
Cypher against graphbuff:
cargo run --release -p graphbuff-server # in-memory, 127.0.0.1:7475
cargo run --release -p graphbuff-server -- --data ./data --persistent # durable
cargo run --release -p graphbuff-server -- --bind 0.0.0.0:7475 --token s3cret
cargo run --release -p graphbuff-server -- --demo movies # start with the movies demo graph
| Request | Answer |
|---|---|
GET /health |
{"status":"ok"} (never needs the token) |
GET /db |
{"databases":[{"name","storage","default","nodes","relationships"}]} |
POST /db/{name}/query |
runs {"query": "...", "params": {...}, "timeoutMs": 5000} against database name (params and timeoutMs optional) |
POST /query |
the same, against the default database |
POST /db/{name}/tx |
begins a transaction: 201 {"transaction":{"id","database","path","timeoutMs"}} |
POST /db/{name}/tx/{id} |
runs {"query", "params", "timeoutMs"} in it; answers like a query |
POST /db/{name}/tx/{id}/commit |
commits: {"committed":true} |
DELETE /db/{name}/tx/{id} |
rolls back (cancelling a running statement): {"rolledBack":true} |
/tx, /tx/{id}, /tx/{id}/commit |
the same, against the default database |
POST /db/{name}/backup |
online backup into --backup-dir: {"backup": "name"}; admins only (details) |
POST /db/{name}/restore |
creates the database from a backup: {"backup": "name", "overwrite": false}; admins only |
POST /db/{name}/check |
consistency check of a persistent database: {"check":{"consistent","errors",...}}; admins only |
A query returns {"columns":[...],"rows":[[...]],"stats":{"nodesCreated":1,...,"containsUpdates":true}}.
A query request is its own transaction. Database commands (CREATE DATABASE,
SHOW DATABASES, USE x MATCH ...) work through either query endpoint.
Transactions: the statements of an explicit transaction may come in separate requests, on any connection, and see each other's changes; other clients see none of them until the commit. While one is open, other writers on its database wait (including
begin), readers do not. A statement that fails rolls the whole transaction back, and its error carries"rolledBack":true. A statement that does not parse, a database command, orUSEof another database is rejected and the transaction stays open. A transaction that gets no request for--tx-timeoutseconds (default 60) is rolled back; requests to a transaction that has ended answer404 TransactionNotFound. Shutting the server down rolls back open transactions.Timeouts:
--query-timeout MSstops a query that runs longer (default: no limit); a request may ask for less with"timeoutMs". The limit also covers the wait for another writer, and the wait to begin a transaction. A query that runs out of time is rolled back and answers408 Timeout; in a transaction the whole transaction rolls back. Rolling back a transaction (and shutting down) cancels the statement it is running, which then answers409 Cancelled.Values: JSON integers become Cypher INTEGERs and numbers with a fraction or exponent become FLOATs, in both directions (floats are always written with
.0or an exponent). NaN and infinities are returned as the strings"NaN","Infinity","-Infinity". Nodes, relationships and paths are objects with a"$type":{"$type":"node","id":0,"labels":["Person"],"properties":{...}},{"$type":"relationship","id":0,"type":"KNOWS","start":0,"end":1,"properties":{...}},{"$type":"path","nodes":[...],"relationships":[...]}.Errors:
{"error":{"code":"SyntaxError","message":"...","offset":9}}with status 400 (SyntaxError,SemanticError,TypeError,RuntimeError,Unsupported,BadRequest), 404 (DatabaseNotFound,TransactionNotFound), 408 (Timeout), 409 (ConstraintError,Cancelled), 401 (missing or wrong credentials), 403 (Forbidden: the user's roles do not allow the statement), 413 (body over 16 MiB, orTransactionTooLarge: a transaction past its database's size cap, rolled back), 500 (StorageError).Security: the server listens on localhost by default. With
--token(or theGRAPHBUFF_TOKENenvironment variable) every request except/healthneedsAuthorization: Bearer <token>; with--users FILE, clients log in as users (see Users and TLS).LOAD CSVis off unless--import-dir DIRis given; it then reads only files insideDIR.Implementation (
crates/server, standard library only, plus rustls with a TLS feature): one thread per connection (at most 256), HTTP/1.1 keep-alive,Content-Lengthor chunked bodies,Expect: 100-continue.Server::startembeds it in a Rust program.
From Java, examples/java/GraphbuffClient.java is
a dependency-free client (Java 17+, java.net.http) with a runnable demo:
java examples/java/GraphbuffClient.java http://127.0.0.1:7475
var db = new GraphbuffClient("http://127.0.0.1:7475", null); // or a token
db.query("CREATE DATABASE movies IF NOT EXISTS", null);
db.query("movies", "CREATE (:Person {name: $name, age: $age})", Map.of("name", "Ann", "age", 31));
var r = db.query("movies", "MATCH (p:Person) RETURN p.name AS name, p.age AS age", null);
String name = (String) r.get(0, "name");
long age = (Long) r.get(0, "age"); // INTEGER -> Long, FLOAT -> Double
With Jackson or Gson in the project, HttpClient plus your JSON library is all you need.
Send {"query": ..., "params": ...} and read columns / rows.
Try it on your machine: one command starts the server with the movies graph. Needs Docker.
$ docker run --rm -p 127.0.0.1:7475:7475 -p 127.0.0.1:7687:7687 ghcr.io/janvencl/graphbuff --demo moviesThen follow Getting started.