Search by

dseguy / php-gremlin

exakat

PHP client for Apache TinkerPop Gremlin Server 4.0 over its HTTP protocol

Package info

github.com/dseguy/gremlin

Homepage

Issues

Language:Gherkin

pkg:composer/dseguy/php-gremlin

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

v0.1.0 2026-09-24 07:19 UTC

This package is not auto-updated.

Last update: 2026-09-25 05:29:25 UTC


README

Packagist License CI

A PHP client for Apache TinkerPop Gremlin Server 4.0, talking to its HTTP endpoint directly (TinkerPop 4 dropped the old WebSocket sub-protocol, so there is no session/handshake layer to manage).

  • Query & fetch — send Gremlin queries, get back plain PHP values, real Vertex/Edge/Path/Property objects, or your own hydrated PHP classes.
  • A fluent Gremlin DSL — $g->V()->out('knows')->filter(...)->order()->by(...) reads like real Gremlin because it renders to real Gremlin-lang text; the server parses and executes it exactly as it would any other client's query.
  • Two wire formats — GraphBinary V4 by default (compact, fast), GraphSON V4 as an explicit opt-in for human-readable debugging.
  • A mass loader — stream GraphML or GraphSON exports into a running server in batches, without loading the whole file into memory.

Everything here was built and verified against a real Gremlin Server 4.0.0-beta.3, including the entire Apache TinkerPop Gherkin conformance suite (437 scenarios, run via Behat — see Testing) — not just unit tests against assumptions about the protocol.

Requirements

  • PHP >= 8.2
  • ext-curl, ext-json
  • A Gremlin Server 4.0 instance to connect to

Installation

composer require dseguy/php-gremlin

Quick start

use Gremlin\Driver\GremlinClient;
use Gremlin\Driver\RemoteConnection;
use Gremlin\Process\Traversal\GraphTraversalSource;
use Gremlin\Process\Traversal\P;
use Gremlin\Process\Traversal\__;
use Gremlin\Structure\Order;

$client = new GremlinClient('localhost', 8182);
$g = new GraphTraversalSource(new RemoteConnection($client));

// Plain values back for plain queries.
$names = $g->V()->hasLabel('person')->values('name')->toList();

// Real Vertex/Edge objects for element-shaped results.
$marko = $g->V()->has('name', 'marko')->next(); // Gremlin\Structure\Vertex
echo $marko->value('age');

// The fluent DSL renders straight to Gremlin-lang text - server-side semantics,
// not a local reimplementation of them.
$adults = $g->V()->out('knows')
    ->filter(__::has('age', P::gt(28)))
    ->order()->by('name', Order::Asc)
    ->values('name')
    ->toList();

// addV()/addE() mutate the graph the same way.
$vertex = $g->addV('person')->property('name', 'alice')->next();

Hydrating into your own classes

Vertex/Edge results can be mapped onto a plain PHP class instead, by property name (id/label are special-cased):

final class Person
{
    public int|string $id;
    public string $name;
    public int $age;
}

$people = $g->V()->hasLabel('person')->hydrateAs(Person::class)->toList();
// list<Person>

Serializers

GraphBinary V4 is the default (Gremlin\Driver\Serializer\GraphBinarySerializerV4). Pass GraphSON explicitly when you want to inspect requests/responses as JSON, e.g. while debugging against curl:

use Gremlin\Driver\Serializer\GraphSONSerializerV4;

$client = new GremlinClient('localhost', 8182, new GraphSONSerializerV4());

Both serializers decode into the exact same PHP shapes - switching between them never changes what your code gets back.

Mass loading GraphML / GraphSON

use Gremlin\IO\BulkLoader;
use Gremlin\IO\GraphMLReader; // or GraphSONReader for TinkerPop's line-delimited export format

$reader = new GraphMLReader('/path/to/export.xml');
$loader = new BulkLoader($g, batchSize: 500);

$result = $loader->load($reader, function (int $vertices, int $edges): void {
    echo "loaded {$vertices} vertices, {$edges} edges so far\n";
});

echo "done: {$result->vertexCount} vertices, {$result->edgeCount} edges\n";

Both readers stream the source file (XMLReader for GraphML, line-by-line for GraphSON) rather than loading it whole, and BulkLoader batches multiple vertices/edges into a single request per batch instead of one round trip per element.

Testing

composer install
vendor/bin/phpunit tests/Unit          # no server needed
vendor/bin/phpunit tests/Integration   # needs a live Gremlin Server 4.0 (see below)
vendor/bin/behat                       # the TinkerPop conformance suite - same requirement
vendor/bin/phpstan analyse

The integration and Behat suites expect a Gremlin Server 4.0 running locally (localhost:8182 for tests/Integration, localhost:8184 with three named toy-graph traversal sources - gmodern/gclassic/gempty - for vendor/bin/behat; see tests/gremlin-test/bootstrap/FeatureContext.php and tests/Integration/LiveServerTest.php for the exact configuration expected). They are not part of CI for that reason - only tests/Unit and PHPStan run there.

tests/gremlin-test/ vendors a curated subset of Apache TinkerPop's own language-agnostic Gherkin feature files under their original Apache-2.0 license; see tests/gremlin-test/VENDORED_FROM.md for provenance and the curation rationale.

License

Apache-2.0. See LICENSE. Files under tests/gremlin-test/features/ originate from the apache/tinkerpop project and retain their original license headers.