aria-php / constellation-client
PHP 8.2+ client library for Constellation scientific identifier resolution service
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.4
Requires (Dev)
- mockery/mockery: ^1.6
- phpunit/phpunit: ^10.0 || ^11.0
This package is auto-updated.
Last update: 2026-07-28 16:51:40 UTC
README
A simple, object-oriented PHP 8.2+ client library for the Constellation scientific identifier resolution and knowledge graph service.
Features
- Async Discovery: Initiate identifier resolution jobs via the discovery endpoint
- Graph Queries: Retrieve knowledge graph fragments with relationships and identifiers
- Provenance Tracking: Query discovery events with full resolver provenance
- JSON-LD Support: Access graph data in semantic web format
- Type-Safe: Immutable value objects with full type hints
- Exception-Based: Clear, specific exceptions for error handling
- Zero Dependencies: Only requires Guzzle for HTTP (commonly available)
Installation
Install via Composer:
composer require constellation/php-client
Requires PHP 8.2 or higher.
Quick Start
use Constellation\Client;
use Constellation\Request\GraphQueryOptions;
// Initialize client
$client = new Client('http://localhost:8080');
// 1. Initiate async discovery
$discovery = $client->discovery()->discover('uniprot', 'P69905');
echo $discovery->jobId; // UUID for tracking
// 2. Query knowledge graph
$graph = $client->graph()->get('uniprot', 'P69905');
echo $graph->entity->label;
// With query options
$options = (new GraphQueryOptions())
->depth(2)
->limit(50)
->offset(0);
$graph = $client->graph()->get('pdb', '1A3N', $options);
// 3. Track discovery provenance
$events = $client->provenance()->events(namespace: 'pdb', limit: 50);
foreach ($events->items as $event) {
echo $event->resolver; // 'PdbResolver'
echo $event->timestamp; // DateTime
echo count($event->discovered); // New identifiers found
}
API Reference
Client
Main entry point for all API operations.
$client = new Client(
baseUrl: 'http://localhost:8080',
httpClient: null, // Optional custom Guzzle client
timeout: 30 // Request timeout in seconds
);
$client->discovery(); // DiscoveryService
$client->graph(); // GraphService
$client->provenance(); // ProvenanceService
Discovery Service
Initiate asynchronous identifier resolution jobs.
$response = $client->discovery()->discover(
namespace: 'uniprot',
accession: 'P69905'
);
// Returns DiscoveryResponse
echo $response->jobId; // UUID string
echo $response->status; // 'queued'
echo $response->identifier->uri; // 'https://identifiers.org/uniprot:P69905'
DiscoveryResponse fields:
jobId: string— Unique job identifier for trackingstatus: string— Current status (typically 'queued')identifier: Identifier— The resolved identifier with URI
Graph Service
Query entity-centric knowledge graph fragments.
// Standard JSON response
$graph = $client->graph()->get(
namespace: 'uniprot',
accession: 'P69905',
options: new GraphQueryOptions() // Optional
);
// JSON-LD response (semantic web format)
$ld = $client->graph()->getLd('pdb', '1A3N');
GraphQueryOptions (fluent builder):
$options = (new GraphQueryOptions())
->depth(2) // 0-3 (default: 1)
->limit(50) // 1-200 (default: 25)
->offset(0); // 0+ (default: 0)
GraphResponse fields:
entity: Entity— The queried entity (id, type, label, metadata)identifiers: IdentifierCollection— All identifiers for this entityrelationships: RelationshipCollection— Outbound and inbound relationshipspagination: array— Query depth, limit, offset
Entity fields:
id: int— Unique entity IDtype: string— Entity type ('Structure', 'Protein', 'Model', etc.)label: string— Human-readable namemetadata: array— Resolver-specific data
Relationship fields:
predicate: string— Relationship type (e.g., 'MAPS_TO_PROTEIN', 'HAS_STRUCTURE')level: int— Discovery depth (0-3)sourceEntity: Entity— Source entitytargetEntity: Entity— Target entity
IdentifierCollection methods:
$collection->getItems(); // Identifier[]
$collection->getTotal(); // int
$collection->count(); // int
$collection->isEmpty(); // bool
$collection->filterByNamespace('pdb'); // Identifier[]
RelationshipCollection methods:
$collection->getOutbound(); // Relationship[] (from queried entity)
$collection->getInbound(); // Relationship[] (to queried entity)
$collection->getAll(); // Relationship[]
$collection->filterOutboundByPredicate('MAPS_TO_PROTEIN');
$collection->filterInboundByPredicate('HAS_STRUCTURE');
$collection->count(); // int
Provenance Service
Query discovery events with provenance metadata.
$response = $client->provenance()->events(
namespace: 'pdb', // Optional filter
accession: '1A3N', // Optional filter
resolver: 'PdbResolver', // Optional filter
limit: 50, // 1-200 (default: 50)
offset: 0 // 0+ (default: 0)
);
foreach ($response->items as $event) {
echo $event->resolver; // Resolver name
echo $event->version; // Resolver version
echo $event->timestamp; // DateTimeImmutable
echo $event->input->namespace;
foreach ($event->discovered as $id) {
echo $id->namespace; // New identifiers found
}
echo $event->metadata['source']; // API source URL
}
ProvenanceResponse fields:
query: array— Filter parameters usedcount: int— Number of events returneditems: ProvenanceEvent[]— Discovery events
ProvenanceEvent fields:
id: int— Event record IDtimestamp: DateTimeImmutable— When discoveredresolver: string— Resolver nameversion: string— Resolver versioninput: Identifier— The identifier that was resolveddiscovered: Identifier[]— New identifiers foundmetadata: array— Resolver-specific metadata
Error Handling
The library throws specific exceptions for different error types:
use Constellation\Exception\InterfaceException;
use Constellation\Exception\DiscoveryException;
use Constellation\Exception\GraphException;
use Constellation\Exception\ProvenanceException;
use Constellation\Exception\NetworkException;
try {
$client->discovery()->discover('uniprot', 'P69905');
} catch (DiscoveryException $e) {
// Discovery endpoint error
echo $e->getMessage();
} catch (NetworkException $e) {
// HTTP/network error (timeout, connection failed, etc.)
echo $e->getMessage();
echo $e->getPrevious(); // Original exception
} catch (InterfaceException $e) {
// Catch all Constellation errors
echo $e->getMessage();
}
Configuration
Custom HTTP Client
For advanced customization, provide your own Guzzle client:
use GuzzleHttp\Client as GuzzleClient;
$httpClient = new GuzzleClient([
'timeout' => 60,
'headers' => ['User-Agent' => 'MyApp/1.0'],
'proxy' => 'http://proxy.example.com:8080',
]);
$client = new Client('http://api.example.com', $httpClient);
Base URL
Default: http://localhost:8080
$client = new Client('https://constellation.example.com:8443');
Request Timeout
Default: 30 seconds
$client = new Client('http://localhost:8080', timeout: 60);
Testing
Run tests with PHPUnit:
composer install
./vendor/bin/phpunit
Tests include:
- Unit Tests: Value object construction, serialization, builder validation
- Integration Tests: Full service workflows with fixture-based mocked HTTP responses
All integration tests use pre-recorded API responses (fixtures) for deterministic, offline testing.
Value Objects
All response models are immutable value objects:
$identifier = new Identifier('uniprot', 'P69905');
$identifier->namespace; // 'uniprot'
$identifier->accession; // 'P69905'
$identifier->uri; // Generated URI
// All properties are readonly
$entity = new Entity(1, 'Protein', 'Human Hemoglobin', ['species' => 'Homo sapiens']);
$entity->id; // 1
$entity->type; // 'Protein'
$entity->label; // 'Human Hemoglobin'
$entity->metadata; // ['species' => 'Homo sapiens']
JSON Serialization
Convert responses to JSON:
$graph = $client->graph()->get('pdb', '1A3N');
$json = json_encode($graph->toArray());
$event = $response->items[0];
$eventJson = json_encode($event->toArray());
JSON-LD Support
Access semantic web linked data format:
$ld = $client->graph()->getLd('pdb', '1A3N');
echo $ld['@context']; // RDF context
echo $ld['@id']; // Entity URI
echo $ld['@type']; // Entity type
echo $ld['label']; // Entity label
foreach ($ld['identifier'] ?? [] as $id) {
echo $id['@id']; // Identifier URI
}
foreach ($ld['relationship'] ?? [] as $rel) {
echo $rel['predicate']; // Relationship type
echo $rel['target']; // Target entity URI
}
Contributing
Contributions are welcome! Please ensure:
- All tests pass
- New code includes unit/integration tests
- PHPDoc comments on all public methods
- Code follows PSR-12 standards
License
MIT
Related
- Constellation API — The server-side API
- Identifiers.org — Scientific identifier URI scheme