CloudEvents
EvidentSource uses the CloudEvents specification as its core event format. CloudEvents is a specification for describing event data in a common way, enabling interoperability across services, platforms, and systems.
Why CloudEvents?
Section titled “Why CloudEvents?”CloudEvents provides:
- Standardization: A vendor-neutral specification backed by the CNCF
- Interoperability: Easy integration with other CloudEvents-compatible systems
- Flexibility: Support for various content types and transport protocols
- Extensibility: Custom attributes for domain-specific needs
CloudEvents Structure
Section titled “CloudEvents Structure”Required Attributes
Section titled “Required Attributes”Every CloudEvent in EvidentSource must have these attributes:
| Attribute | Type | Description |
|---|---|---|
id | String | Unique identifier for the event |
source | URI-reference | Identifies the context in which the event occurred |
specversion | String | CloudEvents specification version (always “1.0”) |
type | String | Type of event related to the source |
Optional Attributes
Section titled “Optional Attributes”EvidentSource supports these optional CloudEvents attributes:
| Attribute | Type | Description |
|---|---|---|
datacontenttype | String | Content type of the data (default: “application/json”) |
dataschema | URI | Schema that the data adheres to |
subject | String | Subject of the event in the context of the source |
time | Timestamp | When the event occurred (ISO 8601) |
data | Any | The event payload |
Example CloudEvent
Section titled “Example CloudEvent”{ "specversion": "1.0", "id": "45a8b444-3d5f-4a6e-b55d-1c5e0b2e4a89", "source": "https://example.com/orders", "type": "com.example.orders.OrderCreated", "subject": "order-12345", "time": "2024-01-15T10:30:00Z", "datacontenttype": "application/json", "dataschema": "https://example.com/schemas/order-created/v1", "data": { "orderId": "12345", "customerId": "67890", "totalAmount": 99.99, "currency": "USD" }}Event Attributes in EvidentSource
Section titled “Event Attributes in EvidentSource”Source
Section titled “Source”The source attribute identifies the system or component that generated the event:
- Use URIs for global uniqueness:
https://api.example.com/order-service - Or use simple identifiers for internal systems:
order-service - Be consistent within your domain
The type attribute describes what happened:
- Use reverse-DNS notation:
com.example.orders.OrderCreated - Or use simple descriptive names:
OrderCreated - Include version if needed:
com.example.orders.OrderCreated.v2
Subject
Section titled “Subject”The subject provides additional context:
- Typically identifies the entity the event is about
- Examples:
order-12345,customer-67890,product-abc - Enables efficient filtering and indexing
The time attribute represents when the event occurred:
- Use ISO 8601 format with timezone
- Represents business time (when the event happened in the real world)
- Different from
recordedtime(when EvidentSource stored the event)
Data Formats
Section titled “Data Formats”JSON Data
Section titled “JSON Data”The most common format for event data:
{ "specversion": "1.0", "id": "...", "source": "inventory-service", "type": "InventoryUpdated", "datacontenttype": "application/json", "data": { "productId": "SKU-123", "quantity": 42, "location": "warehouse-1" }}Binary Data
Section titled “Binary Data”For binary payloads, use base64 encoding:
{ "specversion": "1.0", "id": "...", "source": "document-service", "type": "DocumentScanned", "datacontenttype": "application/pdf", "data_base64": "JVBERi0xLjQKJdPr6eEKMSAwIG9i..."}Structured vs Binary Mode
Section titled “Structured vs Binary Mode”EvidentSource stores events in structured mode:
- Events are stored as complete CloudEvents objects
- All attributes are preserved and queryable
- Enables rich filtering and indexing
Best Practices
Section titled “Best Practices”Event ID Generation
Section titled “Event ID Generation”- Use UUIDs for guaranteed uniqueness
- Never reuse event IDs
- EvidentSource enforces unique IDs per database
val eventId = UUID.randomUUID().toString()Source Design
Section titled “Source Design”Choose meaningful source identifiers:
// Good examples"https://api.acme.com/order-service""order-service.production""acme.orders"
// Avoid"service1""backend""system"Type Naming Conventions
Section titled “Type Naming Conventions”Use consistent, descriptive event types:
// Domain.Entity.Action pattern"com.acme.orders.OrderCreated""com.acme.orders.OrderShipped""com.acme.inventory.StockDepleted"
// Simple Entity.Action pattern"Order.Created""Order.Shipped""Inventory.Depleted"Data Schema Evolution
Section titled “Data Schema Evolution”Plan for schema changes:
- Use dataschema: Reference versioned schemas
- Add, don’t remove: New fields should be optional
- Version when breaking: Create new event types for incompatible changes
- Document changes: Maintain schema documentation
Querying by CloudEvents Attributes
Section titled “Querying by CloudEvents Attributes”EvidentSource indexes events by key attributes:
// Query by sourceEventSelector(stream = "order-service")
// Query by typeEventSelector(eventType = "OrderCreated")
// Query by subjectEventSelector(subject = "order-12345")
// Combine attributesEventSelector( stream = "order-service", eventType = "OrderCreated", subject = "order-12345")Integration Patterns
Section titled “Integration Patterns”Event Routing
Section titled “Event Routing”Use CloudEvents attributes for routing:
when (event.type) { "OrderCreated" -> handleOrderCreated(event) "OrderShipped" -> handleOrderShipped(event) "OrderCancelled" -> handleOrderCancelled(event)}Event Filtering
Section titled “Event Filtering”Filter events based on attributes:
events.filter { event -> event.source == "order-service" && event.type.startsWith("Order") && event.time?.isAfter(startDate) == true}Event Correlation
Section titled “Event Correlation”Use subject for correlation:
// All events for a specific orderval orderEvents = client.queryEvents( EventQuery( eventSelection = EventSelection( selectors = listOf( EventSelector(subject = "order-12345") ) ) ))CloudEvents Extensions
Section titled “CloudEvents Extensions”EvidentSource automatically adds:
recordedtime: When the event was storedrevision: The event’s revision number
These are exposed as CloudEvents extensions and can be accessed alongside standard attributes.
Next Steps
Section titled “Next Steps”- Explore Bi-Temporal Indexing using CloudEvents time attributes
- Learn about Event Sourcing patterns
- Understand State Views for processing CloudEvents
- See the API Reference for CloudEvents operations