SPI object representing a single Business Object Provider (shortly known as BOP).
Contains of two main parts:
- EntityProvider which is an abstract representation of the data structure used by the REST service calls.
- OperationProvider which is an abstract representation of all REST service calls available on that particular set of Entities.
For example, if you have REST service like this:
-
GET /employeeAll
--> Which gets all employees. Lets assume only Fistname and Lastname fields are returned. -
GET /employee/{id}
--> Which gets single employee defined using the given ID. Lets assume all fields (Firstname, Lastname, Age and Salary) are returned. -
CREATE /employee
--> Which creates new employee. -
DELETE /employee/{id}
--> Which delete employee using the given ID. -
UPDATE /employee/{id}
--> Which updates data for employee with the given ID.
- One EntityProvider with a single Entity named "Employee" which will consists of Property for each field/column these REST calls are working with. So in the case described above you will have four Properties: "Firstname", "Lastname", "Age" and "Salary" inside your Employee Entity.
- One OperationProvider with a single Operation created for each of these REST calls. Those Operations needs to be described precisely using OperationBuilder, OperationInput and OperationOutput objects so that Application Builder allow Business User to use only UI features that are supported by these REST call itself. For example Operation that correspond to the GET/employeeAll REST call, need to define and use different OperationOutput because the REST call returns only two fields instead of the full set of them. Based to that information, Application Builder UI addapt automatically.
This object is pure, fully-customizable BOP with no restrictions. If you don't need any special treatment and rather looking for some simplification where you don't need to take care about parsing dependencies, generating static RT code and other parts of the Extension lifecycle, you can alternatively use SimpleBOP which is build on top the plain BOP and takes care of those stuff for you.
- Version:
- 17.1.1
- Source:
- See:
Example
define([
'{{package}}/js/CustomEntityProvider',
'{{package}}/js/CustomOperationProvider'
], function (
CustomEntityProvider,
CustomOperationProvider
) {
var CustomBOP = function () {
};
CustomBOP.prototype.getEntityProvider = function () {
return new CustomEntityProvider();
};
CustomBOP.prototype.getOperationProvider = function () {
return new CustomOperationProvider();
};
CustomBOP.prototype.getId = function () {
return 'my.custom.bop';
};
return new CustomBOP();
});
Methods
getEntityProvider() → {bop/js/spi/entity/EntityProvider}
stable API
Returns an instance of EntityProvider associated with this BOP.
- Version:
- 17.1.1
- Source:
Returns:
Examples
CustomBOP.prototype.getEntityProvider = function () {
return new 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;
});
getId() → {String}
stable API
Gets an unique identifier of this BOP.
- Version:
- 17.1.1
- Source:
Returns:
- Type
- String
getOperationProvider() → {bop/js/spi/operation/OperationProvider}
stable API
Returns an instance of OperationProvider associated with this BOP.
- Version:
- 17.1.1
- Source:
Returns:
Examples
CustomBOP.prototype.getOperationProvider = function () {
return new 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() {
// 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;
});