Skip to main content

Domain modelling

Entity Factory

If Domain modelling is enabled, the SDK provides a Factory for entities. The factory offers methods to create new entity objects, grouped by the namespaces in which the entities are defined. After creation, the properties of the entity can be accessed. The created entity objects can then e.g. be used as input for services or commands.

Create new entity

The example below shows how to create entities using the factory:

// Create an Entity using entity factory
const entity1 = this.factory.entity.nsacrnm.Entityidentifier();
// Access entity1 properties
entity1.propIdentifier = 'some property value';


// Create a Root Entity using entity factory
const root1 = this.factory.entity.nsacrnm.RootEntityIdentifier();
// Access root1 properties
root1.propIdentifier = 'some property value';


// Create an Input Entity using entity factory
const input = this.factory.entity.nsacrnm.Service1_Input();
// Access input properties
input.propIdentifier = 'some property value';

Entity instance check

In the implementation file of a service, command, agent and operation entity instance check can be done through isInstanceOf functionality, the entity instance check will also check for the entity hierarchy.

// check an object
if (this.isInstanceOf.entity.ns1.BlueCar(car)) {
// now one can access the special property that only blue car has
const prop = car.specialPropOfBlueCar;
}

// check BlueCar is a Car (Since BlueCar is a child of Car, the entity instance check will also check for the entity hierarchy)
if (this.isInstanceOf.entity.ns1.Car(blueCar)) {
// now one can access the special property that only car has
const prop = blueCar.specialPropOfCar;
}

Implement Domain Services

Within a domain service implementation, you can access the modelled input properties and process any logic. Typical logic in domain services would be e. g. loading of data from the repo and processing the data or calling instance and factory commands. Additionally it is also possible to define the output of the service. Both input and output is restricted to what has been modelled in the Solution Designer.

  /**
* Domain service execution
*/
public async execute(): Promise<void> {

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

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

// trigger instanceCommand
await myInstance.MyCommand();

// fill output of service with some data
this.output = this.factory.entity.order.ServiceIdentifier_Output();
this.output.prop1 = property1;
this.output.prop2 = property2;
}

Trigger Domain Services

The generated SDK provides functions to easily trigger domain services from other places in the service.

Input and output entity

When triggering a domain service, it might be necessary to provide an input entity. The Entity factory can be used to create new input entities, which could be set as input parameter for the service.

If there is an output defined for the domain service, it is returned as a result and can be used for further processing.

Trigger domain service

The following code shows how to trigger a domain service, for example from another service implementation.

// Initialize service input via factory and assign value to input properties
const input = this.factory.entity.nsacrnm.ServiceIdentifier_Input();
input.property1 = 'Some property value';

// Trigger a domain service
const output = await this.services.nsacrnm.ServiceIdentifier(input);

// Access service output
const val = output.propIdentifier;

Implement Error handling

When implementing domain logic, there are three types of errors which can happen and need to be handled:

  • Business errors which can occur if business conditions are not met, but are expected to happen
  • Validation errors
  • General errors (all others)

Throw business errors

For every modelled business error, the SDK offers functionality to throw it.

Within the implementation file of a service, command or agent the following code can be used to throw a business error:

throw this.factory.error.nsacrnm.MyBusinessError();

Every error thrown in an implementation file should be handled latest in the errorHandler method of the API operation.

Handle errors

In the implementation file of a service, command, agent and operation error instance check can be done by using isInstanceOf functionality, thus enable to code handling logic for different error instances.

Handling business errors

To safely handle a business error that was modelled in the Solution Designer use the following code:

try {
// call a service which might throw a business error
await this.services.nsacrnm.ServiceIdentifier(input);
} catch (e) {
// check whether the error matches any of the errors modelled in Solution Designer
if (this.isInstanceOf.businessError.ns1.NoBalanceAvailable(e)) {
// now can handle this specific business error
}

if (this.isInstanceOf.error.ValidationError(e)) {
// now can handle this validation error
}

if (this.isInstanceOf.businessError.ns2.NoCustomerFound(e)) {
// now can handle this specific business error
}
}

Handling general errors

These are the general errors that can occur. To safely handle an error, use the following code:


try {
// execute some logic
} catch (e) {

// check whether the validation of an entity (used as input or instance) fails
if (this.isInstanceOf.error.ValidationError(e)) {
// now can handle this validation error
}

// check for a child of abstract BusinessError
if (this.isInstanceOf.error.BusinessError(e)) {
// now can handle this Business error
}

// check whether an action (e.g. a command) is not currently available
if (this.isInstanceOf.error.ActionNotAvailableError(e)) {
// now can handle this ActionNotAvailable error
}

// check whether an aggregate is found in the datastore
if (this.isInstanceOf.error.AggregateNotFound(e)) {
// now can handle this AggregateNotFound error
}

// check whether an external request (i.e. this.util.request) caused an error
if (this.isInstanceOf.error.ExternalRequestError(e)) {
// now can handle this ExternalRequest error
}

// check whether an internal request caused an error
if (this.isInstanceOf.error.InternalRequestError(e)) {
// now can handle this InternalRequest error
}

// check for GeneralError
if (this.isInstanceOf.error.GeneralError(e)) {
// now can handle this general error
}
}
warning

The hierarchy of error consists of GeneralError, ValidationError and BusinessError, where ValidationError and BusinessError extend GeneralError.