SPI object for creating simplified BOP implementations.
By implementing SimpleBOP, you're choosing more restricted SPI which on the other don't require that much effort to be written properly. If you're looking for pure, fully-customizable BOP with no restrictions write your own ExtensionManager and use BOP interface with BOPRegistry API object to register it into Application Builder data model.
Obviously both options (SimpleBOP and BOP) has some pros and cons. Here is short list:
SimpleBOP - Pros:
- No need to take care of ExtensionManager lifecycle manually.
- No need to write method generating RT code manually.
- No need to manually define BOPs ID as it's taken automatically based on the extension ID.
- No need to take care of BOPExtensionDependencyFormat to register only selected Entities and Properties into the Application Builder data model.
- You can't apply CustomParameters as you're out of control over the ExtensionManager lifecycle and thus you can't process them anyhow.
- Generally, you're restricted only to the simplied expectations and you can't define more custom behavior.
- Opposite of Pros & Cons from SimpleBOP.
- Version:
- 17.1.1
- Source:
- See:
Example
define([], function () {
var CustomBOP = function () {
};
CustomBOP.prototype.getEntityProviderPath = function () {
return '{{package}}/js/CustomEntityProvider';
};
CustomBOP.prototype.getOperationProviderPath = function () {
return '{{package}}/js/CustomOperationProvider';
};
return CustomBOP;
});
Methods
getEntityProviderPath() → {String}
stable API
Gets relative path to the corresponding EntityProvider.
Returned string can contain special {{package}}
identifier which will be automatically transformed into the path that correspond to your extension top-level package.
- Version:
- 17.1.1
- Source:
Returns:
- Type
- String
Examples
CustomBOP.prototype.getEntityProviderPath = function () {
return '{{package}}/js/CustomEntityProvider';
};
define([
'bop/js/api/entity/DataModelFactory',
'entity/js/api/PropertyType'
], function (
DataModelFactory,
PropertyType
) {
var CustomEntityProvider = function () {
var firstname = DataModelFactory.createProperty({
id: 'my.custom.bop.Employee.Firstname',
name: 'Firstname',
type: PropertyType.TEXT
});
var lastname = DataModelFactory.createProperty({
id: 'my.custom.bop.Employee.Lastname',
name: 'Lastname',
type: PropertyType.TEXT
});
var age = DataModelFactory.createProperty({
id: 'my.custom.bop.Employee.Age',
name: 'Age',
type: PropertyType.NUMBER
});
var employee = DataModelFactory.createEntity({
id: 'my.custom.bop.Employee',
singularName: 'Employee',
pluralName: 'Employees',
properties: [firstname, lastname, age]
});
this._entities = [employee];
};
CustomEntityProvider.prototype.getEntities = function() {
return this._entities;
};
return CustomEntityProvider;
});
getOperationProviderPath() → {String}
stable API
Gets relative path to the corresponding OperationProvider.
Returned string can contain special {{package}}
identifier which will be automatically transformed into the path that correspond to your extension top-level package.
The constructor will be passed an representation of the dependencies that can be used to access configuration parameters and configure BOPAuthenticator
- Version:
- 17.1.1
- Source:
Returns:
- Type
- String
Examples
CustomBOP.prototype.getOperationProviderPath = function () {
return '{{package}}/js/CustomOperationProvider';
};
define([
'bop/js/api/operation/OperationBuilder',
'bop/js/api/operation/OperationInput',
'bop/js/api/operation/OperationOutput',
'operation/js/api/Operation',
'operation/js/api/Operator',
'{{package}}/js/Employee'
], function (
OperationBuilder,
OperationInput,
OperationOutput,
Operation,
Operator,
Employee
) {
var CustomOperationProvider = function () {
this._operations = [];
var employee = Abcs.Entities().findById('my.custom.bop.Employee');
var id = employee.getProperty('my.custom.bop.Employee.ID');
var firstname = employee.getProperty('my.custom.bop.Employee.Firstname');
var lastname = employee.getProperty('my.custom.bop.Employee.Lastname');
var age = employee.getProperty('my.custom.bop.Employee.Age');
var partialOutput = new OperationOutput({
entity: employee
}).property(firstname).
property(lastname);
var idInput = new OperationInput({
entity: employee
}).parameter({
property: id,
required: true
});
var firstnameLastnameInput = new OperationInput({
entity: employee
}).parameter(firstname).
parameter(lastname).
operators([
Operator.EQUALS,
Operator.NOT_EQUALS,
Operator.STARTS_WITH,
Operator.ENDS_WITH,
Operator.CONTAINS,
Operator.NOT_CONTAINS
]);
var getAllEmployees = new OperationBuilder({
name: 'Find all Employees',
type: Operation.Type.READ_MANY,
performs: function() {
// Lets assume there is an Employee object as part of our BOP extension implementation which builds the URL based
// on the "operationInputData" values, makes the real REST call and returns relevant OperationResult instance
return Promise.resolve(Employee.getAll());
}
}).description('Longer description of what this Operation does').
returns(partialOutput).
takes(firstnameLastnameInput).
build();
var getEmployeeByID = new OperationBuilder({
name: 'Find Employee by ID',
type: Operation.Type.READ_ONE,
performs: function(operationInputData) {
// Lets assume there is an Employee object as part of our BOP extension implementation which builds the URL based
// on the "operationInputData" values, makes the real REST call and returns relevant OperationResult instance
return Promise.resolve(Employee.findByID(operationInputData));
}
}).specialType(Operation.SpecialType.QUERY_BY_ID).
takes(idInput).
returns(employee).
build();
// Register all relevant operations
this._operations.push(getAllEmployees);
this._operations.push(getEmployeeByID);
// ..include the same for all other REST calls
};
CustomOperationProvider.prototype.getOperations = function() {
return this._operations;
};
return CustomOperationProvider;
});