genesisdb/client-sdk

There is no license information available for the latest version (1.0.6) of this package.

PHP SDK for GenesisDB

Maintainers

Package info

github.com/genesisdb-io/genesisdb-io-client-php

pkg:composer/genesisdb/client-sdk

Statistics

Installs: 3

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.6 2026-03-05 19:10 UTC

This package is not auto-updated.

Last update: 2026-03-05 19:13:29 UTC


README

This is the official PHP SDK for GenesisDB, an awesome and production ready event store database system for building event-driven apps.

GenesisDB Advantages

  • Incredibly fast when reading, fast when writing 🚀
  • Easy backup creation and recovery
  • CloudEvents compatible
  • GDPR-ready
  • Easily accessible via the HTTP interface
  • Auditable. Guarantee database consistency
  • Logging and metrics for Prometheus
  • SQL like query language called GenesisDB Query Language (GDBQL)
  • ...

Installation

composer require genesisdb/client-sdk

Configuration

Basic Setup

use GenesisDB\GenesisDB\Client;

$client = new Client(
    apiUrl: 'http://localhost:8080',
    apiVersion: 'v1',
    authToken: '<secret>'
);

Streaming Events

Basic Event Streaming

// Stream all events for a subject
$events = $client->streamEvents('/customer');

Stream Events from Lower Bound

use GenesisDB\GenesisDB\StreamOptions;

$events = $client->streamEvents('/', new StreamOptions(
    lowerBound: '2d6d4141-6107-4fb2-905f-445730f4f2a9',
    includeLowerBoundEvent: true
));

Stream Events with Upper Bound

$events = $client->streamEvents('/', new StreamOptions(
    upperBound: '9f3e4141-7208-4fb2-905f-445730f4f3b1',
    includeUpperBoundEvent: false
));

Stream Events with Both Lower and Upper Bounds

$events = $client->streamEvents('/', new StreamOptions(
    lowerBound: '2d6d4141-6107-4fb2-905f-445730f4f2a9',
    includeLowerBoundEvent: true,
    upperBound: '9f3e4141-7208-4fb2-905f-445730f4f3b1',
    includeUpperBoundEvent: false
));

Stream Latest Events by Event Type

$events = $client->streamEvents('/', new StreamOptions(
    latestByEventType: 'io.genesisdb.app.customer-updated'
));

This feature allows you to stream only the latest event of a specific type for each subject. Useful for getting the current state of entities.

Committing Events

Basic Event Committing

use GenesisDB\GenesisDB\CommitEvent;

$client->commitEvents([
    new CommitEvent(
        source: 'io.genesisdb.app',
        subject: '/customer',
        type: 'io.genesisdb.app.customer-added',
        data: [
            'firstName' => 'Bruce',
            'lastName' => 'Wayne',
            'emailAddress' => 'bruce.wayne@enterprise.wayne'
        ]
    ),
    new CommitEvent(
        source: 'io.genesisdb.app',
        subject: '/customer',
        type: 'io.genesisdb.app.customer-added',
        data: [
            'firstName' => 'Alfred',
            'lastName' => 'Pennyworth',
            'emailAddress' => 'alfred.pennyworth@enterprise.wayne'
        ]
    ),
    new CommitEvent(
        source: 'io.genesisdb.store',
        subject: '/article',
        type: 'io.genesisdb.store.article-added',
        data: [
            'name' => 'Tumbler',
            'color' => 'black',
            'price' => 2990000.00
        ]
    ),
    new CommitEvent(
        source: 'io.genesisdb.app',
        subject: '/customer/fed2902d-0135-460d-8605-263a06308448',
        type: 'io.genesisdb.app.customer-personaldata-changed',
        data: [
            'firstName' => 'Angus',
            'lastName' => 'MacGyver',
            'emailAddress' => 'angus.macgyer@phoenix.foundation'
        ]
    )
]);

Preconditions

Preconditions allow you to enforce certain checks on the server before committing events. GenesisDB supports multiple precondition types:

isSubjectNew

Ensures that a subject is new (has no existing events):

use GenesisDB\GenesisDB\Precondition;

$client->commitEvents([
    new CommitEvent(
        source: 'io.genesisdb.app',
        subject: '/user/456',
        type: 'io.genesisdb.app.user-created',
        data: [
            'firstName' => 'John',
            'lastName' => 'Doe',
            'email' => 'john.doe@example.com'
        ]
    )
], [
    Precondition::isSubjectNew('/user/456')
]);

isSubjectExisting

Ensures that events exist for the specified subject:

$client->commitEvents([
    new CommitEvent(
        source: 'io.genesisdb.app',
        subject: '/user/456',
        type: 'io.genesisdb.app.user-updated',
        data: [
            'firstName' => 'John',
            'lastName' => 'Doe',
            'email' => 'john.doe@example.com'
        ]
    )
], [
    Precondition::isSubjectExisting('/user/456')
]);

isQueryResultTrue

Evaluates a query and ensures the result is truthy. Supports the full GDBQL feature set including complex WHERE clauses, aggregations, and calculated fields.

Basic uniqueness check:

$client->commitEvents([
    new CommitEvent(
        source: 'io.genesisdb.app',
        subject: '/user/456',
        type: 'io.genesisdb.app.user-created',
        data: [
            'firstName' => 'John',
            'lastName' => 'Doe',
            'email' => 'john.doe@example.com'
        ]
    )
], [
    Precondition::isQueryResultTrue(
        "STREAM e FROM events WHERE e.data.email == 'john.doe@example.com' MAP COUNT() == 0"
    )
]);

Business rule enforcement (transaction limits):

$client->commitEvents([
    new CommitEvent(
        source: 'io.genesisdb.banking',
        subject: '/user/123/transactions',
        type: 'io.genesisdb.banking.transaction-processed',
        data: [
            'amount' => 500.00,
            'currency' => 'EUR'
        ]
    )
], [
    Precondition::isQueryResultTrue(
        "STREAM e FROM events WHERE e.subject UNDER '/user/123' AND e.type == 'transaction-processed' AND e.time >= '2024-01-01T00:00:00Z' MAP SUM(e.data.amount) + 500 <= 10000"
    )
]);

Complex validation with aggregations:

$client->commitEvents([
    new CommitEvent(
        source: 'io.genesisdb.events',
        subject: '/conference/2024/registrations',
        type: 'io.genesisdb.events.registration-created',
        data: [
            'attendeeId' => 'att-789',
            'ticketType' => 'premium'
        ]
    )
], [
    Precondition::isQueryResultTrue(
        "STREAM e FROM events WHERE e.subject UNDER '/conference/2024/registrations' AND e.type == 'registration-created' GROUP BY e.data.ticketType HAVING e.data.ticketType == 'premium' MAP COUNT() < 50"
    )
]);

Generic precondition (forward-compatible with future server releases):

$client->commitEvents([
    new CommitEvent(
        source: 'io.genesisdb.app',
        subject: '/test',
        type: 'io.genesisdb.app.test-created',
        data: ['key' => 'value']
    )
], [
    Precondition::generic('someCustomFuturePrecondition', ['foo' => 'bar', 'baz' => 123])
]);

Supported GDBQL Features in Preconditions:

  • WHERE conditions with AND/OR/IN/BETWEEN operators
  • Hierarchical subject queries (UNDER, DESCENDANTS)
  • Aggregation functions (COUNT, SUM, AVG, MIN, MAX)
  • GROUP BY with HAVING clauses
  • ORDER BY and LIMIT clauses
  • Calculated fields and expressions
  • Nested field access (e.data.address.city)
  • String concatenation and arithmetic operations

If a precondition fails, the commit returns HTTP 412 (Precondition Failed) with details about which condition failed.

GDPR Compliance

Store Data as Reference

use GenesisDB\GenesisDB\CommitEventOptions;

$client->commitEvents([
    new CommitEvent(
        source: 'io.genesisdb.app',
        subject: '/user/456',
        type: 'io.genesisdb.app.user-created',
        data: [
            'firstName' => 'John',
            'lastName' => 'Doe',
            'email' => 'john.doe@example.com'
        ],
        options: new CommitEventOptions(storeDataAsReference: true)
    )
]);

Delete Referenced Data

$client->eraseData('/user/456');

Observing Events

Basic Event Observation

foreach ($client->observeEvents('/customer') as $event) {
    echo "Received event: " . $event->getType() . "\n";
    echo "Data: " . json_encode($event->getData()) . "\n";
}

Observe Events from Lower Bound (Message Queue)

foreach ($client->observeEvents('/customer', new StreamOptions(
    lowerBound: '2d6d4141-6107-4fb2-905f-445730f4f2a9',
    includeLowerBoundEvent: true
)) as $event) {
    echo "Received event: " . $event->getType() . "\n";
}

Observe Events with Upper Bound (Message Queue)

foreach ($client->observeEvents('/customer', new StreamOptions(
    upperBound: '9f3e4141-7208-4fb2-905f-445730f4f3b1',
    includeUpperBoundEvent: false
)) as $event) {
    echo "Received event: " . $event->getType() . "\n";
}

Observe Events with Both Bounds (Message Queue)

foreach ($client->observeEvents('/customer', new StreamOptions(
    lowerBound: '2d6d4141-6107-4fb2-905f-445730f4f2a9',
    includeLowerBoundEvent: true,
    upperBound: '9f3e4141-7208-4fb2-905f-445730f4f3b1',
    includeUpperBoundEvent: false
)) as $event) {
    echo "Received event: " . $event->getType() . "\n";
}

Observe Latest Events by Event Type (Message Queue)

foreach ($client->observeEvents('/customer', new StreamOptions(
    latestByEventType: 'io.genesisdb.app.customer-updated'
)) as $event) {
    echo "Received latest event: " . $event->getType() . "\n";
}

Querying Events

$results = $client->queryEvents(
    'STREAM e FROM events WHERE e.type == "io.genesisdb.app.customer-added" ORDER BY e.time DESC LIMIT 20 MAP { subject: e.subject, firstName: e.data.firstName }'
);

foreach ($results as $result) {
    echo "Result: " . json_encode($result) . "\n";
}

Health Checks

// Check API status
$pingResponse = $client->ping();
echo "Ping response: " . $pingResponse . "\n";

// Run audit to check event consistency
$auditResponse = $client->audit();
echo "Audit response: " . $auditResponse . "\n";

License

MIT

Author