skip to main content

Additional GraphQL services

Cloudlet's GraphQL API allows you to acquire and release locks on objects and retrieve historical records for classes for which versioning is enabled.

Reference engine model #

All examples on this page reference the engine model in figure:

Employee

The Employee class, center, as modeled in the Tutorial.

The Employee class has system versioning enabled.

lock and unlock services. #

In order to support concurrent change scenarios, the GraphQL schema offers two services that allow you to acquire or release locks on the database concerning one or more objects: Mutation.lock and Mutation.unlock.

type Mutation {
  lock(locks: [EntityID!], minutes: Int = 10): LockStatusResult
  unlock(locks: [EntityID!]): LockStatusResult
}

Unlike other services, these are model-independent in that they are not bound to a specific class. Both require a list of input type of type EntityID as input, and return the LockStatusResult structure as output. Let’s examine them in order:

input EntityID {
  entityName: EntityName!
  _id: ID!
}

The input EntityID represents a database object identified by its ID and class name, given in the entityName field. This is of type EntityName, an enum containing a value for each class present in the GraphQL schema. For example, for reference model, EntityName contains the following values:

enum EntityName {
  Address
  Employee
  Project
  Project_assignment
  Qualification
  Team
}

Every EntityID is is moreover meant to univocally identify a resource to lock or release the lock on. Let’s examine the output LockStatusResult:

type LockStatusResult {
  locked: Boolean!
  minutes: Int!
}

This structure indicates whether the requested entity is locked (locked=true) or unlocked (locked=false) and for how many minutes it is locked (minutes). By default, the lock service requires a 10-minute lock on the chosen entity, but you can increase (or decrease) this duration by properly setting the optional minutes argument.

Retrieve historical versions of an object #

Background: what is versioning?

Starting with Livebase version 5.8.3, for classes for which versioning (or system versioning) is enabled, the <ClassName> structure is extended with the following fields:

type ClassName {
_id: ID
_clientId: ID
_versionStart: Datetime(format: String = "default")
_versionEnd: Datetime(format: String = "default")

# attributes, outgoing roles, associates...
# ...
}

_versionStart is a timestamp indicating the start of that version’s validity interval (analogous to row_start), while _versionEnd indicates the end of that version’s validity interval (analogous to row_end). You can request _versionStart and _versionEnd in any service that returns the <ClassName> structure (representing the most recent object version).

Beyond this change, the schema generates the following additional read services for versioned classes:

getVersion service. #

The Query.<ClassName>___getVersion service allows obtaining a versioned version of an object graph from an object of a certain class.

type Query {
  ClassName___getVersion(_id: ID!, atVersion: Datetime!): ClassName
}

The service requests the ID of the object to be retrieved and the version’s timestamp as input, and it returns the corresponding structure <ClassName> as output. The version of <ClassName> returned is the one whose range (row_start, row_end) includes the timestamp atVersion passed as a parameter.

For example, the service to retrieve the historical version of an Employee object is as follows:

type Query {
  Employee___getVersion(_id: ID!, atVersion: Datetime!): Employee
}

getVersionPage service. #

The Query.<ClassName>___getVersionPage service allows you to get a list of historical versions of a graph of objects from an object of a certain class.

type Query {
  ClassName___getVersionPage(_id: ID!, ClassNamePageOptions options): ClassNamePage
}

The service requests as input the ID of the object to be retrieved and returns as output the structure <ClassName>Page, which contains a list of the historical versions
of the object. You can control the subset of objects returned by the page by properly setting the optional options argument, of type <ClassName>PageOptions.

The result can be filtered and/or sorted using all of the pre-existing <ClassName>PageOptions, which is added the ability to sort by the _versionStart and _versionEnd fields.

input ClassNamePageOptions {
orderBy: [ClassNameSort!] = [_id___ASC]
# ...
}

enum ClassNameSort {
_id___ASC
_id___DESC
_versionStart___ASC
_versionStart___DESC
_versionEnd___ASC
_versionEnd___DESC
# ...
}

For example, the service to retrieve the list of historical versions of an Employee object is as follows:

type Query {
  Employee___getVersionPage(_id: ID!, options: EmployeePageOptions): EmployeePage
}