Objects
Objects are the core data entities in OpenRegister that store and manage structured information. This document explains everything you need to know about working with objects.
Overview
An object in OpenRegister represents a single record of data that:
- Conforms to a defined schema
- Belongs to a specific register
- Has a unique UUID identifier
- Can contain nested objects and file attachments
- Maintains version history through audit logs
- Can be linked to other objects via relations
Object Structure
Each object contains:
id: Unique UUID identifieruri: Absolute URL to access the objectversion: Semantic version number (e.g. 1.0.0)register: The register this object belongs toschema: The schema this object must conform toobject: The actual data payload as JSONfiles: Array of related file IDsrelations: Array of related object IDstextRepresentation: Text representation of the objectlocked: Lock status and detailsowner: Nextcloud user that owns the objectauthorization: JSON object describing access permissionsupdated: Last modification timestampcreated: Creation timestamp
Key Features
Schema Validation
- Objects are validated against their schema definition
- Supports both soft and hard validation modes
- Ensures data integrity and consistency
Relations & Nesting
- Objects can reference other objects via UUIDs or URLs
- Supports nested object structures up to configured depth
- Maintains bidirectional relationship tracking
Version Control
- Automatic version incrementing
- Full audit trail of changes
- Historical version access
- Ability to revert to any previous version
- Detailed change tracking between versions
Access Control
- Object-level ownership
- Granular authorization rules
- Lock mechanism for concurrent access control
File Attachments
- Support for file attachments
- Secure file storage integration
- File metadata tracking
API Operations
Objects support standard CRUD operations:
- Create new objects
- Read existing objects
- Update object data
- Delete objects
- Search and filter objects
- Export object data
- Revert to previous versions
Object Locking and Versioning
Version Control and Revert Functionality
OpenRegister provides comprehensive version control capabilities:
- Every change creates a new version with full audit trail
- Changes are tracked at the field level
- Previous versions can be viewed and compared
- Objects can be reverted to any historical version
- Revert operation creates new version rather than overwriting
- Audit logs maintain full history of all changes including reverts
- Revert includes all object properties including relations and files
- Batch revert operations supported for related objects
Locking Objects
Objects can be locked to prevent concurrent modifications. This is useful when:
- Long-running processes need exclusive access
- Multiple users/systems are working on the same object
- Ensuring data consistency during complex updates
Object Locking Sequence
The following diagram illustrates the object locking process:
Object Deletion States
Objects in OpenRegister follow a lifecycle with soft deletion and purging capabilities:
Object Relations
Objects in OpenRegister support sophisticated relationships through schema definitions. The way objects relate to each other depends on how you configure properties in your schema.
Schema Property Configuration Options
When defining a property in a schema that references other objects, you have several configuration options:
For Single Objects (type: 'object')
{
"type": "object",
"objectConfiguration": {
"handling": "nested-object" // or "nested-schema", "related-schema", "uri"
},
"$ref": "schema-id-or-slug",
"inversedBy": "property-name",
"register": "register-id-or-slug",
"cascadeDelete": true
}
For Arrays of Objects (type: 'array')
{
"type": "array",
"items": {
"type": "object",
"$ref": "schema-id-or-slug",
"inversedBy": "property-name",
"register": "register-id-or-slug",
"cascadeDelete": true
},
"objectConfiguration": {
"handling": "nested-object" // or "nested-schema", "related-schema", "uri"
}
}
Schema Reference Configuration ($ref and register)
When defining object relationships in your schema properties, OpenRegister uses two key configuration options to determine where and how to store or reference related objects:
$ref Property
The $ref property specifies which schema the related object should conform to. The backend supports two formats:
-
Simple schema reference: Just the schema ID or name
"$ref": "organisation-schema" -
Path-based reference: A path where the schema name is extracted from the last segment
"$ref": "path/to/organisation-schema"
Backend Resolution Logic:
- If
$refcontains a/, the backend extracts everything after the last slash - Otherwise, it uses the value directly as the schema identifier
- This value is passed as the
schemaparameter when creating or updating related objects
register Property
The register property specifies which register the related object belongs to:
"register": "my-register-id"
Backend Behavior:
- If
registeris specified, related objects are created/updated in that register - If
registeris omitted, the current object's register is used as the default - This ensures related objects can be stored in different registers if needed
Complete Configuration Example
Here's how these properties work together in a schema configuration:
{
"properties": {
"deelnemers": {
"type": "array",
"items": {
"$ref": "organisation-schema",
"register": "organisations-register",
"inversedBy": "deelnames",
"writeBack": true,
"removeAfterWriteBack": true
}
}
}
}
What happens when saving:
- Backend identifies that
deelnemerscontains organization objects - Uses
organisation-schemato validate and structure the objects - Stores/updates objects in the
organisations-register - Sets up inverse relations via the
deelnamesproperty - Handles write-back operations as configured
Use Cases
Same Register Relations:
{
"community": {
"type": "object",
"$ref": "community-schema"
// register omitted - uses current object's register
}
}
Cross-Register Relations:
{
"members": {
"type": "array",
"items": {
"$ref": "person-schema",
"register": "people-register",
"inversedBy": "communities"
}
}
}
This configuration system allows for flexible object relationships while maintaining proper data organization across different registers and schemas.
Object Handling Types
When defining object relationships in your schema properties, you can specify how related objects should be handled using the handling configuration option within objectConfiguration. OpenRegister supports four different handling types, each with specific behaviors for storage and retrieval:
1. Nested Object (nested-object)
Description: Stores object data directly within the parent object as embedded JSON data.
Behavior:
- Object data is stored inline within the parent object's JSON structure
- No separate database entity is created for the nested object
- Changes to the nested object are saved as part of the parent object
- Best for simple, tightly coupled data that doesn't need independent lifecycle management
Example Schema Configuration:
{
"address": {
"type": "object",
"objectConfiguration": {
"handling": "nested-object"
},
"properties": {
"street": {"type": "string"},
"city": {"type": "string"},
"zipCode": {"type": "string"}
}
}
}
Resulting Data Structure:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "John Doe",
"address": {
"street": "Main Street 1",
"city": "Amsterdam",
"zipCode": "1000 AA"
}
}
2. Nested Schema (nested-schema)
Description: Stores object as a separate entity in the database but embeds the full object data in API responses.
Behavior:
- Creates a separate
ObjectEntityin the database with its own UUID - Object follows the schema specified in
$ref - During rendering, the full nested object data is included in the response
- Allows independent lifecycle management while providing convenient access to nested data
- Supports cascade operations when configured with
inversedBy
Example Schema Configuration:
{
"profile": {
"type": "object",
"$ref": "profile-schema",
"objectConfiguration": {
"handling": "nested-schema"
},
"inversedBy": "owner",
"register": "users"
}
}
Resulting Data Structure:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "John Doe",
"profile": {
"id": "987fcdeb-51a2-43d7-8f9e-123456789abc",
"bio": "Software developer",
"skills": ["PHP", "JavaScript", "Vue.js"],
"owner": "123e4567-e89b-12d3-a456-426614174000"
}
}
3. Related Schema (related-schema)
Description: Stores object as a separate entity and references it by UUID/ID only.
Behavior:
- Creates a separate
ObjectEntityin the database with its own UUID - Only the UUID reference is stored in the parent object
- Client must make additional API calls to retrieve the full nested object data
- Provides the most separation and independence between objects
- Optimal for loosely coupled relationships and large datasets
- Supports cascade operations when configured with
inversedBy
Example Schema Configuration:
{
"department": {
"type": "object",
"$ref": "department-schema",
"objectConfiguration": {
"handling": "related-schema"
},
"inversedBy": "employees",
"register": "organization"
}
}
Resulting Data Structure:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "John Doe",
"department": "456e7890-e12b-34c5-d678-901234567890"
}
4. URI Reference (uri)
Description: References external objects by URI/URL without local storage.
Behavior:
- No local
ObjectEntityis created - Stores only the URI reference as a string
- External object is not managed by OpenRegister
- Useful for referencing objects in external systems or APIs
- No cascade operations or local validation
- Client is responsible for resolving the URI to retrieve object data
Example Schema Configuration:
{
"externalService": {
"type": "object",
"objectConfiguration": {
"handling": "uri"
},
"format": "uri"
}
}
Resulting Data Structure:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "John Doe",
"externalService": "https://api.external.com/services/auth-service-v2"
}
Handling Type Comparison
| Feature | Nested Object | Nested Schema | Related Schema | URI Reference |
|---|---|---|---|---|
| Separate Entity | ❌ | ✅ | ✅ | ❌ |
| Independent Lifecycle | ❌ | ✅ | ✅ | ✅ |
| Embedded in Response | ✅ | ✅ | ❌ | ❌ |
| Cascade Operations | ❌ | ✅ | ✅ | ❌ |
| Schema Validation |