Skip to main content
Subjects are the core data entities in TAPLE Core. Each subject represents a traceable asset or entity with its own state and event history. This guide explains how to create and manage subjects.

Understanding Subjects

A subject in TAPLE Core contains:
  • Subject ID: Unique identifier derived from governance, schema, and public key
  • State: Current properties stored as JSON
  • Event Chain: Immutable history of all changes
  • Governance: Rules governing the subject’s behavior
  • Ownership: Public key of the current owner
The Subject struct is defined in core/src/commons/models/state.rs:18.

Subject Data Structure

pub struct Subject {
    pub keys: Option<KeyPair>,
    pub subject_id: DigestIdentifier,
    pub governance_id: DigestIdentifier,
    pub sn: u64,
    pub genesis_gov_version: u64,
    pub public_key: KeyIdentifier,
    pub namespace: String,
    pub name: String,
    pub schema_id: String,
    pub owner: KeyIdentifier,
    pub creator: KeyIdentifier,
    pub properties: ValueWrapper,
    pub active: bool,
}

Creating a Subject

1
Generate Subject Keys
2
Generate cryptographic keys for the new subject:
3
let subject_key = api
    .add_keys(KeyDerivator::Ed25519)
    .await?;
4
Create the Request
5
Compose a Create event request:
6
let create_request = EventRequest::Create(StartRequest {
    governance_id: governance_id.clone(),
    schema_id: "asset".to_string(),
    namespace: "company-namespace".to_string(),
    name: "Asset-001".to_string(),
    public_key: subject_key,
});
7
Sign and Submit
8
Sign the request and submit it:
9
let signed_request = Signed::<EventRequest> {
    content: create_request.clone(),
    signature: Signature::new(&create_request, &owner_keypair)?,
};

let request_id = api.external_request(signed_request).await?;

Retrieving Subjects

Get a Single Subject

Retrieve a subject by its identifier:
let subject = api
    .get_subject(subject_id)
    .await?;
Implemented in core/src/api/api.rs:278. Returns SubjectData with all subject information.

Get All Subjects

Retrieve all subjects with optional pagination:
let subjects = api
    .get_subjects(
        "namespace".to_string(),
        None,  // from: starting point
        Some(10),  // quantity: max results
    )
    .await?;
The from parameter supports negative values for reverse pagination, starting from the end of the collection.

Get Subjects by Governance

Retrieve all subjects under a specific governance:
let subjects = api
    .get_subjects_by_governance(
        governance_id,
        None,  // from
        Some(20),  // quantity
    )
    .await?;
See core/src/api/api.rs:179 for the implementation.

Get Governance Subjects

Retrieve subjects belonging to a specific governance:
let gov_subjects = api
    .get_governance_subjects(
        governance_id,
        None,  // from
        None,  // quantity
    )
    .await?;
Implemented in core/src/api/api.rs:386.

Subject State Management

Get Subject Context

Obtain the context for evaluating operations:
let context = subject.get_subject_context(invoker);
This returns a SubjectContext with governance, schema, ownership status, state, and namespace.

Calculate State Hash

Get the hash of the current state:
let state_hash = subject.get_state_hash(derivator)?;
Implemented in core/src/commons/models/state.rs:199.

Preview State After Patch

Calculate what the state hash would be after applying a patch:
let new_hash = subject.state_hash_after_apply(json_patch, derivator)?;
Useful for validation before applying changes. See core/src/commons/models/state.rs:211.

Updating Subjects

Update Subject State

Apply a JSON patch to update the subject:
subject.update_subject(json_patch, new_sn)?;
This applies the patch and increments the sequence number.

Transfer Subject Ownership

Transfer a subject to a new owner:
subject.transfer_subject(
    new_owner,
    new_public_key,
    new_keys,
    sn,
);
Implemented in core/src/commons/models/state.rs:186.

Subject Lifecycle

Mark Subject as End-of-Life

Deactivate a subject:
subject.eol_event();
Sets the active flag to false. Defined in core/src/commons/models/state.rs:208.

Check Subject Status

Verify if a subject is still active:
if subject.active {
    // Subject is active
} else {
    // Subject has been deactivated
}

Database Operations

Store a Subject

Persist a subject to the database:
db.set_subject(&subject_id, subject)?;
Implemented in core/src/database/db.rs:133.

Retrieve from Database

Load a subject from storage:
let subject = db.get_subject(&subject_id)?;
See core/src/database/db.rs:129.

Get All Subjects from Database

Retrieve all subjects without pagination:
let all_subjects = db.get_all_subjects();
Returns a Vec<Subject> of all stored subjects.

Delete a Subject

Remove a subject from the database:
db.del_subject(&subject_id)?;
Deleting subjects removes them permanently. Ensure you have proper backups or archival processes.

Subject Indexing

Index by Governance

Create an index linking subjects to their governance:
db.set_governance_index(&subject_id, &governance_id)?;

Get Subjects by Governance Index

Retrieve subject IDs for a governance:
let subject_ids = db.get_subjects_by_governance(&governance_id)?;
Implemented in core/src/database/db.rs:334.

Preauthorized Subjects

Add Preauthorization

Allow specific providers to access a subject before it’s created:
let providers = HashSet::new();
providers.insert(provider_key_id);

api.add_preauthorize_subject(&subject_id, &providers).await?;
Defined in core/src/api/api.rs:318.

Get Preauthorized Subjects

Retrieve all preauthorized subjects and their providers:
let preauth = api
    .get_all_allowed_subjects_and_providers(
        None,  // from
        None,  // quantity
    )
    .await?;

Subject ID Generation

Subject IDs are deterministically generated:
let subject_id = generate_subject_id(
    &namespace,
    &schema_id,
    public_key.to_str(),
    governance_id.to_str(),
    governance_version,
    derivator
)?;
Implemented in core/src/commons/models/state.rs:230. The ID is derived from:
  • Namespace
  • Schema ID
  • Public key
  • Governance ID
  • Governance version

Best Practices

  1. Unique Naming: Use descriptive names and namespaces for subjects
  2. Key Management: Securely store subject keys, especially for owned subjects
  3. State Validation: Always validate state against schemas before updates
  4. Pagination: Use pagination for large subject collections to avoid memory issues
  5. Monitoring: Track subject sequence numbers to detect missed events

Error Handling

Common errors when working with subjects:
  • NotFound: Subject doesn’t exist
  • InvalidParameters: Malformed subject ID or parameters
  • InternalError: Database or internal processing error
  • NotCreateEvent: Attempted to create subject from wrong event type

Build docs developers (and LLMs) love