Implement domains

External entities

The external entity script contains 3 parts:

Constructor

The constructor is used to construct a local instance of the external entity and initialize the associated properties with certain pre-specified values that are provided as input properties.

//**
* constructor method of external entity reference
*/
public create(): void {
   const log = this.util.log;
   log.debug('Constructor.execute()');

   // Initialize the value of the associated properties to the input value store in the construc-tor parameter and to a predefined value
   this.instance.associatedProperty1 = this.input.constructorProperty1;
   this.instance.associatedProperty1 = value1;
}

Loader

The loader is used to load the external instance. This is normally done by calling a REST service of the integration namespace.

When calling a service (REST or normal) it is important to check whether the output exists, and it is not void. Due to type safety, if the check does not occur, then it is not possible to access the properties of the returned object. This is to prevent accessing properties that may not exist. This check is necessary for calling functions that are built to return two different types such as services that return either void or their output entity.

/**
* load method of external entity reference - loads external entity from external system
*/
public async load(): Promise<void> {
   const log = this.util.log;
   log.debug('Load.execute()');
   
  // Initialize the input of the REST integration service
   const input = this.factory.entity.cust. ServiceIdentifier_Input();

  // Initialize the input properties to their values
   input.property1 = “value1”; // or this.instance.(…)

  // Call the REST service and pass as input the the input entity created above
   const serviceOutput = await this.services.intnsacrnm.ServiceIdentifier (input);

   // Check if the output of the service is not void
   if(serviceOutput) {
     
     // Initialize the output of the loader of the external entity
     this.output = this.factory.nsacrnm.ExternalEntityIdentifier_Output()

     // Set the values of the output properties of the output
     this.output.property1 = serviceOutput.property1;
     this.output.property2 = serviceOutput.property2; 
   }
}

Validator

The validator gives information regarding the existence of a specific instance of an external entity. It usually returns true if the external instance exists and false if it does not exist. The validator can also be used for updating the local instance of an external entity if the update flag is set to true.

Tip: In a validator it is recommended to try to load the instance. If the instance is returned successfully, then return true. A validator must always return a boolean.
/**
* validate method of external entity reference - checks if external entity still exists in external system
* @param update indicates whether local properties should be updated after validating entity on external system
* @returns boolean indicating whether external entity still exists in external system
*/
public async validate(update: boolean): Promise<boolean> {
    const log = this.util.log;
    log.debug('Validate.execute()');

    // trigger load function of external entity in order to validate whether the entity still exists
    const existence = await this.instance.load();

    // If it exists return true. Otherwise, return false.
    if(existence) {
      return true;
    } else {
      return false;
    }
}

Factory commands

The main purpose of a factory command is to set values to the properties of the entity and then persist those changes to the database, thus, creating a new instance.

The factory command to create an instance of an entity called order is the following:

// Exemplary implementation:
// Assign the created entity to this.instance. This will also ensure type safety
// and the factory command will return the correct instanceId automatically

// Get input to the factory command
const {inputProperty1, inputProperty2} = this.input;

// Set the instance properties to their corresponding input values
this.instance.property1 = inputProperty1;
this.instance.property2 = inputProperty2;

// Set the instance property to an initial value
this.instance.property3 = value3;
// Save changes to the database
await this.instance.persist();

Instance commands

The implementation of an instance command called AcceptOrder which manipulates the state of an instance of the root entity Order is shown below:

// If a condition is met, throw a business error
if( condition ){
  throw this.factory.error.nsacrnm.MyBusinessError(); 
} else { // if condition not satisfied update the value of property1 to the value newValue
  this.instance.property1 = newValue;
}
// Save changes to the database
await this.instance.persist();

To delete an instance of a root entity:

// If a condition is met, throw a business error
this.instance.delete();
Attention: When deleting an instance, remove the line that persists the changes made to an instance of a root entity to the database. Since it was deleted, that line will lead to errors.

Events

An event is published by using the structure of the following code:

// Initialize the event type
const event = this.factory.event.OrderAccepted();
// Initialize the value of the payload properties
event.payload.property1 = value1;
// Publish the event
await event.publish();

Agents

An event that was triggered, will call an agent. This agent will receive the payload of the event as input, and then it will call a service.

// Get the payload of the event that triggered the agent
const { payloadproperty1, payloadproperty2 } =  this.input;

// Initialize the input and call the service GetOrderByNo
const input = this.factory.entity.order.ServiceIdentifier_Input();
// Initialize the property of the input entity
input.property1 = payloadproperty1;

// Call service and pass as input the input entity created above
await this.services.order.ServiceIdentifier(input);

Domain services

The implementation of a domain service is shown below:

// Get the input properties
const {property1, pproperty2, id} =  this.input;

// Get an instance by ID
const insatnce1 = await this.repo.nsacrnm.EntityIdentifier.findById(id);

// Check if instance exists
if(insatnce1){
   // Initialize the output 
   this.output = this.factory.entity.order.ServiceIdentifier_Output();
   // Initialize the values of the output properties
   this.output.property1 = value1;
   this.output.property2 = value2;
}
Note: If you are using the aggregate persistence functionality, please ensure that your code is compliant with the recommended restrictions of the used database. Consult MongoDB documentation for further information. For example: Because of the limitations of database operations and drivers, MongoDB does not recommend the use of timestamps, that are not within the year range of 0 - 9999, see Date and DateTime documentation.