dual-native / http-system
Framework-agnostic PHP library implementing the Dual-Native Pattern with CID validation, bidirectional linking, and zero-fetch optimization
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/dual-native/http-system
Requires
- php: ^7.4|^8.0
Requires (Dev)
- phpunit/phpunit: ^9.0
README
A framework-agnostic PHP library implementing the Dual-Native Pattern for synchronized Human Representation (HR) and Machine Representation (MR) content delivery with Content Identity (CID) validation, bidirectional linking, and zero-fetch optimization.
This library implements the Dual-Native Pattern as defined in the Dual-Native Core Specification and Whitepaper, providing a production-ready implementation of the 5 pillars: Resource Identity (RID), Content Identity (CID), Bidirectional Linking, Semantic Equivalence, and Cataloging & Discovery.
Features
- π Framework-Agnostic: Works with WordPress, Laravel, Symfony, or standalone
- π Content Identity (CID): SHA-256 based version validators for zero-fetch optimization
- π Bidirectional Linking: Automatic navigation between HR and MR
- π¦ Resource Catalog: Registry of dual-native resources with efficient discovery
- π Safe Write Operations: Optimistic concurrency control with CID validation
- β Semantic Equivalence: Validation that HR and MR represent the same content
- ποΈ Dependency Injection: Clean architecture with pluggable adapters
- π§ͺ Well-Tested: 14 PHPUnit tests (32 assertions) with 100% core coverage
Installation
Install via Composer:
composer require dual-native/http-system
Requirements
- PHP 8.0 or higher
- PSR-4 autoloading support
Quick Start
Basic Usage (Standalone)
<?php require 'vendor/autoload.php'; use DualNative\HTTP\DualNativeSystem; use DualNative\HTTP\Events\NullEventDispatcher; use DualNative\HTTP\Storage\InMemoryStorage; // Initialize with null implementations (no external dependencies) $system = new DualNativeSystem( ['version' => '1.0.0'], new NullEventDispatcher(), new InMemoryStorage() ); // Compute Content Identity (CID) $content = ['title' => 'Hello World', 'body' => 'Content here']; $cid = $system->computeCID($content); echo "CID: $cid\n"; // sha256-<hex> // Validate CID $isValid = $system->validateCID($content, $cid); echo "Valid: " . ($isValid ? 'Yes' : 'No') . "\n"; // Generate bidirectional links $links = $system->generateLinks('resource-123', 'https://example.com/page', 'https://api.example.com/resource/123'); print_r($links);
WordPress Integration
<?php use DualNative\HTTP\DualNativeSystem; use DualNative\HTTP\Events\WordPressEventDispatcher; use DualNative\HTTP\Storage\WordPressStorage; // Initialize with WordPress adapters $system = new DualNativeSystem( [ 'version' => '1.0.0', 'profile' => 'full', 'cache_ttl' => 3600 ], new WordPressEventDispatcher(), // Bridges to do_action/apply_filters new WordPressStorage() // Bridges to get_option/update_option ); // Now WordPress hooks work through the library add_action('dual_native_system_initialized', function($system) { // System is ready });
See MIGRATION-GUIDE.md for complete WordPress plugin integration instructions.
Laravel Integration
<?php use DualNative\HTTP\DualNativeSystem; use DualNative\HTTP\Events\EventDispatcherInterface; use DualNative\HTTP\Storage\StorageInterface; // Create Laravel adapters class LaravelEventDispatcher implements EventDispatcherInterface { public function dispatch(string $eventName, ...$args): void { event($eventName, $args); } public function filter(string $filterName, $value, ...$args) { return $value; // Or implement Laravel's equivalent } public function hasListeners(string $eventName): bool { return Event::hasListeners($eventName); } } class LaravelStorage implements StorageInterface { public function get(string $key, $default = null) { return cache()->get($key, $default); } public function set(string $key, $value): bool { return cache()->put($key, $value, 3600); } public function delete(string $key): bool { return cache()->forget($key); } public function has(string $key): bool { return cache()->has($key); } } // Initialize system $system = new DualNativeSystem( config('dualnative'), new LaravelEventDispatcher(), new LaravelStorage() );
Core Concepts
This library provides the business logic for the Dual-Native Pattern. When used in HTTP contexts, CIDs map to ETags for conditional requests (If-Match, If-None-Match), enabling 304 Not Modified responses for unchanged resources and 412 Precondition Failed for conflicting writes. See the WordPress plugin for a complete HTTP implementation example.
Content Identity (CID)
CIDs are SHA-256 hashes of canonical JSON representations, used as ETags for efficient caching:
$content = ['title' => 'My Post', 'body' => 'Content...']; // Compute CID $cid = $system->computeCID($content); // Result: sha256-abc123... // Validate CID (for safe writes) if ($system->validateCID($content, $expectedCid)) { // Content hasn't changed, safe to update }
Safe Write Operations
Prevent conflicting updates using optimistic concurrency control:
// Get current resource $resource = $system->getResource('post-123'); $currentCid = $resource['cid']; // Update with CID validation $result = $system->updateResource( 'post-123', $newData, $currentCid // Must match current state ); if ($result['success']) { $newCid = $result['new_cid']; } else { // 412 Precondition Failed - resource was modified by another process $actualCid = $result['actual_cid']; }
Resource Catalog
Maintain a registry of dual-native resources:
// Create a resource $result = $system->createResource( 'post-123', // Resource ID ['url' => 'https://example.com/post'], // Human Representation ['api_url' => 'https://api.example.com/post/123', 'title' => '...'], // Machine Representation ['author' => 'John Doe'] // Metadata ); // Get catalog $catalog = $system->getCatalog( $since = '2024-01-01T00:00:00Z', // Only resources updated since $filters = ['status' => 'publish'], $limit = 100, $offset = 0 );
Bidirectional Links
Generate navigation links between HR and MR:
$links = $system->generateLinks( 'post-123', 'https://example.com/post-123', // Human Representation URL 'https://api.example.com/posts/123' // Machine Representation URL ); // Result: // [ // 'hr' => ['url' => '...', 'rel' => 'self', 'type' => 'text/html'], // 'mr' => ['url' => '...', 'rel' => 'alternate', 'type' => 'application/json'] // ]
Architecture
The library follows a clean architecture with dependency injection:
βββββββββββββββββββββββββββββββββββ
β Your Application β
β (WordPress/Laravel/Symfony) β
ββββββββββββββ¬βββββββββββββββββββββ
β uses
βΌ
βββββββββββββββββββββββββββββββββββ
β DualNativeSystem β
β (Main Orchestrator) β
βββββββββββββββββββββββββββββββββββ€
β ββ CIDManager β
β ββ LinkManager β
β ββ CatalogManager β
β ββ ValidationEngine β
β ββ HTTPRequestHandler β
βββββββββββββββββββββββββββββββββββ
β
ββββββββ΄βββββββ
βΌ βΌ
βββββββββββ βββββββββββ
β Event β β Storage β
βInterfaceβ βInterfaceβ
βββββββββββ βββββββββββ
β β
βΌ βΌ
βββββββββββ βββββββββββ
βFrameworkβ βFrameworkβ
β Adapter β β Adapter β
βββββββββββ βββββββββββ
Interfaces
EventDispatcherInterface: Framework-agnostic event dispatching
dispatch(string $eventName, ...$args): voidfilter(string $filterName, $value, ...$args)hasListeners(string $eventName): bool
StorageInterface: Framework-agnostic data persistence
get(string $key, $default = null)set(string $key, $value): booldelete(string $key): boolhas(string $key): bool
Adapters
Included:
WordPressEventDispatcher- Bridges to WordPressdo_action()/apply_filters()WordPressStorage- Bridges to WordPressget_option()/update_option()NullEventDispatcher- No-op implementation for testingInMemoryStorage- Array-based storage for testing
Create your own: Implement the interfaces for your framework (Laravel, Symfony, etc.)
Testing
The library includes a comprehensive test suite:
# Install dependencies composer install # Run tests vendor/bin/phpunit # Expected output: # PHPUnit 9.6.29 by Sebastian Bergmann and contributors. # .............. 14 / 14 (100%) # OK (14 tests, 32 assertions)
API Reference
DualNativeSystem
Constructor
new DualNativeSystem( array $config = [], ?EventDispatcherInterface $eventDispatcher = null, ?StorageInterface $storage = null )
Content Identity
// Compute CID for content $system->computeCID($content, ?array $excludeKeys = null): string // Returns: 'sha256-<hex>' // Validate CID matches content $system->validateCID($content, string $expectedCID, ?array $excludeKeys = null): bool // Returns: true if CID matches, false otherwise
Resource Management
// Create a dual-native resource $system->createResource(string $rid, $hr, $mr, array $metadata = []): array // Returns: // [ // 'rid' => 'resource-123', // 'cid' => 'sha256-...', // 'hr' => [...], // 'mr' => [...], // 'links' => ['hr' => [...], 'mr' => [...]], // 'catalog_updated' => true // ] // Get resource by RID $system->getResource(string $rid): ?array // Returns: resource array or null if not found // [ // 'rid' => 'resource-123', // 'hr' => ['url' => '...'], // 'mr' => ['api_url' => '...', 'content_id' => '...'], // 'cid' => 'sha256-...', // 'updatedAt' => '2024-01-01T00:00:00Z' // ] // Update resource with CID validation (safe write) $system->updateResource(string $rid, $newData, string $expectedCid): array // Returns on success: // [ // 'success' => true, // 'rid' => 'resource-123', // 'new_cid' => 'sha256-...', // 'resource' => [...] // ] // Returns on failure (CID mismatch): // [ // 'success' => false, // 'error' => 'CID mismatch - resource has been modified by another process', // 'rid' => 'resource-123', // 'expected_cid' => 'sha256-abc...', // 'actual_cid' => 'sha256-xyz...' // ]
Catalog
// Get catalog of resources $system->getCatalog(?string $since, array $filters, int $limit, int $offset): array // Returns: // [ // 'count' => 42, // 'items' => [ // ['rid' => '...', 'cid' => '...', 'updatedAt' => '...', ...], // ... // ] // ]
Links
// Generate bidirectional links $system->generateLinks(string $rid, string $hrUrl, string $mrUrl): array // Returns: // [ // 'hr' => ['url' => '...', 'rel' => 'self', 'type' => 'text/html'], // 'mr' => ['url' => '...', 'rel' => 'alternate', 'type' => 'application/json'] // ]
Validation
// Validate semantic equivalence between HR and MR $system->validateSemanticEquivalence($hrContent, $mrContent, ?array $scope): array // Returns: // [ // 'equivalent' => true, // 'differences' => [], // 'scope' => ['title', 'body', 'author'] // ] // Or on mismatch: // [ // 'equivalent' => false, // 'differences' => ['title' => ['hr' => 'Title A', 'mr' => 'Title B']], // 'scope' => ['title', 'body', 'author'] // ] // Validate system conformance to dual-native standards $system->validateConformance(array $systemInfo): array // Returns: // [ // 'conformant' => true, // 'level' => 2, // Conformance level (1-4) // 'checks' => [ // 'has_rid' => true, // 'has_cid' => true, // 'has_bidirectional_links' => true, // 'has_catalog' => true // ], // 'issues' => [] // ]
Health Check
// Perform system health check $system->healthCheck(): array // Returns: // [ // 'status' => 'healthy', // 'healthy' or 'degraded' // 'timestamp' => '2024-01-01T00:00:00+00:00', // 'version' => '1.0.0', // 'components' => [ // 'cid_manager' => true, // 'link_manager' => true, // 'catalog_manager' => true, // 'validation_engine' => true, // 'http_handler' => true // ], // 'profile' => 'full' // ]
Configuration
Default configuration:
[
'version' => '1.0.0',
'profile' => 'full',
'exclude_fields' => ['cid', 'etag', '_links', 'modified', 'modified_gmt'],
'cache_ttl' => 3600
]
Events
When using an event dispatcher, the library dispatches these events:
dual_native_system_initialized- System initializeddual_native_created_resource- Resource createddual_native_bidirectional_links- Links generateddual_native_link_header- Link header generateddual_native_computed_cid- CID computeddual_native_catalog_updated- Catalog updated
Performance
- Zero-Fetch Optimization: 90%+ reduction in unchanged content transfers
- CID-based Caching: Efficient conditional requests with ETags
- Bandwidth Savings: 83%+ reduction compared to full content fetching
Use Cases
- WordPress Sites: Add machine-readable APIs to existing WordPress content
- Headless CMS: Provide synchronized HR/MR for decoupled architectures
- API Versioning: Use CIDs for efficient cache validation
- Content Distribution: Efficient content synchronization across systems
- Real-time Systems: Detect content changes without fetching full resources
Documentation
- MIGRATION-GUIDE.md - Integrating with WordPress plugin
- Packagist - Package information
- GitHub - Source code
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
GPL-2.0-or-later - GNU General Public License v2.0 or later
Credits
Developed by the Dual-Native Team
Support
- Issues: GitHub Issues
- Email: antunjurkovic@gmail.com