Skip to main content

Event-Driven Architecture

Overview​

OpenRegister implements a comprehensive event-driven architecture built on Nextcloud's IEventDispatcher (PSR-14 compatible). Every mutation across all entity types dispatches a typed PHP event that can be consumed by any Nextcloud app, delivered to external systems via webhooks, or pushed to real-time subscribers via GraphQL SSE.

The architecture distinguishes between:

  • Pre-mutation events (e.g., ObjectCreatingEvent) — implement StoppableEventInterface so hooks can reject or modify operations before persistence
  • Post-mutation events (e.g., ObjectCreatedEvent) — notify downstream systems after persistence is complete

Event Types​

Object Events​

Event ClassTriggerStoppable
ObjectCreatingEventBefore object insertYes
ObjectCreatedEventAfter successful insertNo
ObjectUpdatingEventBefore object updateYes
ObjectUpdatedEventAfter successful updateNo
ObjectDeletingEventBefore object deleteYes
ObjectDeletedEventAfter successful deleteNo

Pre-mutation events carry the object entity. Update events carry both $oldObject (snapshot before change) and $newObject (the incoming state).

Other Entity Events​

Events are dispatched for mutations on all entity types:

EntityEvents
RegisterRegisterCreating/Created/Updating/Updated/Deleting/Deleted
SchemaSchemaCreating/Created/Updating/Updated/Deleting/Deleted
SourceSourceCreating/Created/Updating/Updated/Deleting/Deleted
ConfigurationConfigurationCreating/Created/Updating/Updated/Deleting/Deleted
ViewViewCreating/Created/Updating/Updated/Deleting/Deleted
AgentAgentCreating/Created/Updating/Updated/Deleting/Deleted
ApplicationApplicationCreating/Created/Updating/Updated/Deleting/Deleted
ConversationConversationCreating/Created/Updating/Updated/Deleting/Deleted
OrganisationOrganisationCreating/Created/Updating/Updated/Deleting/Deleted

All entity types follow the same before/after naming convention, giving 39+ typed event classes in total.

Consuming Events​

Any Nextcloud app can subscribe to OpenRegister events by registering an event listener in its Application.php:

use OCA\OpenRegister\Event\ObjectCreatedEvent;

$dispatcher->addListener(ObjectCreatedEvent::class, function (ObjectCreatedEvent $event) {
$object = $event->getObject();
// react to the new object
});

Stopping Propagation​

Pre-mutation events implement StoppableEventInterface. A listener can reject an operation:

$dispatcher->addListener(ObjectCreatingEvent::class, function (ObjectCreatingEvent $event) {
if (!$this->validate($event->getObject())) {
$event->stopPropagation(); // object will NOT be persisted
}
});

This is the mechanism used by Schema Hooks and reference validation.

Event Payload (CloudEvents v1.0)​

When events are forwarded to external systems (webhooks, realtime SSE), payloads conform to CloudEvents v1.0:

{
"specversion": "1.0",
"type": "nl.conduction.openregister.object.created",
"source": "https://nextcloud.example.nl/apps/openregister",
"id": "evt-abc123",
"time": "2026-03-21T12:00:00Z",
"datacontenttype": "application/json",
"data": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"register": "meldingen-register",
"schema": "meldingen",
"object": { ... }
}
}

Event Listeners (Internal)​

OpenRegister ships 8 internal event listeners in lib/Listener/:

ListenerEventsPurpose
WebhookEventListener55+ events across all entitiesDispatches webhook deliveries
SchemaHookListenerObjectCreating/Updating/DeletingFires synchronous schema hooks
AuditTrailListenerAll object eventsWrites audit trail entries
RelationIntegrityListenerObjectDeleting/UpdatingEnforces referential integrity
GraphQLSubscriptionListenerAll object eventsBridges events to SSE subscription buffer
SearchIndexListenerObjectCreated/Updated/DeletedKeeps Solr/Elasticsearch index current
RetentionListenerObjectCreatedApplies default archival metadata
NotificationListenerAll object eventsEvaluates notification rules

The DeepLinkRegistrationEvent is dispatched during Application::boot(). Consuming Nextcloud apps listen for this event to register URL templates for OpenRegister schema/register combinations. See Deep Link Registry.

Standards​

StandardRole
CloudEvents v1.0Webhook and external event payload format
PSR-14Event dispatcher interface (IEventDispatcher)
StoppableEventInterfacePre-mutation rejection mechanism