Skip to content

Cross Module API

Ray Fung edited this page Feb 16, 2026 · 4 revisions

Cross-Module API

The Cross-Module API allows modules to expose and consume typed commands through a provider/consumer handshake. This enables service-style communication between independent modules without tight coupling.

How It Works

The flow is:

  1. Provider registers API commands via Agent::addAPICommand() in __onReady().
  2. Consumer requests an API handle via Agent::getAPI() in __onReady().
  3. Framework performs a handshake: calls the provider's __onAPICall() with the consumer's module code.
  4. If the provider grants access, the consumer receives an API object and can invoke commands.

Defining an API Provider

// In controller __onReady()
public function __onReady(Agent $agent): bool
{
    // Register commands with the API
    $agent->addAPICommand('getVersion', function() {
        return '1.0.0';
    });

    $agent->addAPICommand('processData', function($data) {
        // Process and return result
        return strtoupper($data);
    });

    return true;
}

Authorizing the Handshake

// Provider's controller
public function __onAPICall(Agent $agent, string $moduleCode): bool
{
    // Grant access to specific modules
    return in_array($moduleCode, [
        'demo/consumer_module',
        'demo/another_module',
    ]);
}

⚠️ Warning: Security: Always validate the caller's module code in __onAPICall(). Returning true unconditionally allows any module to call your API.

Consuming an API

// Consumer's controller __onReady()
public function __onReady(Agent $agent): bool
{
    $api = $agent->getAPI('demo/provider_module');

    if ($api) {
        // Invoke the provider's command
        $version = $api->exec('getVersion');
        $result  = $api->exec('processData', 'hello');
    }

    return true;
}

API Class Reference

Method Return Description
exec(string $command, ...$args) mixed Execute a registered API command
has(string $command) bool Check if a command exists
getModuleCode() string Get the provider's module code

Agent API Methods

Method Context Description
addAPICommand(string $name, callable $callback) Provider Register a callable command in your API
getAPI(string $moduleCode) Consumer Request API handle from another module

Best Practices

  • Register API commands in __onReady(), not __onInit(), as all modules must be initialized first.
  • Use __onAPICall() to whitelist consumers by module code.
  • Always check the return value of getAPI() — it returns null if the handshake is denied.
  • Keep API commands focused and well-named to serve as a stable contract between modules.

Event-System Database

Clone this wiki locally