Reserving IDs and checksums

When you add a one-to-one child to a parent resource, there are two additional behaviors to configure:

  • Reserving ID values for one-to-one child instances
  • Modifying the parent's checksum calculation to include fields in the child

Reserving IDs in composite requests

Normally, ID values for new objects are not specified until the data is committed to the database.

In the context of a composite request, multiple objects can be created in each subrequest, but none of the objects are committed until the end of the composite request. There may be situations where you need to know the ID of an object created in a subrequest, even though that object has not yet been committed to the database.

To address this issue, when a base configuration entity is used in a composite request, it can reserve an ID value. This allows an ID value to be assigned to the object, even though the data has not yet been committed.

You can configure a one-to-one child so that it also reserves ID values in composite requests.

Note that IDs are reserved in composite requests only when both the parent and child are created in the same POST. If a POST specifies only fields on the parent and the child fields are specified in a later composite subrequest PATCH, then the child ID does not get reserved and is set when the composite request completes.

Adding child fields to parent checksums

A checksum is a string value that identifies the "version" of a particular resource. Checksums are useful when you want to modify or delete an object and you want to verify that the object has not been modified by some other process since the last time you read it.

In most cases, an object's checksum is calculated using only the fields on the corresponding data model entity. For example, the checksum for an Activity is calculated using only the fields declared directly on the Activity entity.

When you add a one-to-one child to a parent schema, you typically want the checksum to include fields from the one-to-one child. This means that the checksum value changes if there are changes to fields on the parent entity or the one-to-one child entity. For example, if the Activity resource is enhanced with a one-to-one ActivityLegalInfo_Ext child resource, then the checksum for an Activity resource ought to be calculated using fields declared directly on the Activity entity and fields declared on the ActivityLegalInfo_Ext entity.

Configuring ID and checksum behaviors

Every base configuration entity has an ExtResource class that you can use to extend the functionality of the resource. These classes are located in the gw.rest.ext package.

To reserve IDs for new one-to-one child entities, add the following method override to the class. The <childResource> reference must be changed to the name of the one-to-one child resource.

  override function finishCreate(data : DataEnvelope, batchUpdateMap : BatchUpdateMap) {
    super.finishCreate(data, batchUpdateMap)
    reserveIdsIfNecessary({this.Element.<childResource>})
  }

To extend checksums to include child fields, add the following getter override to the class. The <childResource> reference must be changed to the name of the one-to-one child resource.

  override property get Checksum() : String {
    return ChecksumUtil.extendChecksumWithEntities(super.Checksum, {this.Element.<childResource>})
  }

For example, the following code is the complete ActivityExtResource class with extensions for the ActivityLegalInfo_Ext one-to-one child.

package gw.rest.ext.cc.common.v1.activities

uses gw.api.modules.rest.framework.v1.batch.BatchUpdateMap
uses gw.api.modules.rest.framework.v1.checksum.ChecksumUtil
uses gw.api.modules.rest.framework.v1.json.DataEnvelope
uses gw.rest.core.cc.common.v1.activities.ActivityCoreResource

@Export
class ActivityExtResource extends ActivityCoreResource {

  override function finishCreate(data : DataEnvelope, batchUpdateMap : BatchUpdateMap) {
    super.finishCreate(data, batchUpdateMap)
    reserveIdsIfNecessary({this.Element.ActivityLegalInfo_Ext})
  }

  override property get Checksum() : String {
    return ChecksumUtil.extendChecksumWithEntities(super.Checksum, {this.Element.ActivityLegalInfo_Ext})
  }
  
}