Multi-Service Data Provider 2
The vb/MultiServiceDataProvider2 built-in instance factory type is a data provider implementation that combines multiple vb/ServiceDataProvider2 instance factory variables, each providing a unique fetch capability.
Often components that bind to data providers, like oj-combobox-one and oj-select-single (or the -many variants), require or use different 'fetch' capabilities on the data provider implementation.
For example, an oj-select-single component might call fetchFirst() (on the DataProvider implementation) to populate its options, and then call fetchByKeys() to fetch data for selected value, and fetchByOffset() to fetch items from an offset. Often the endpoint configured on a ServiceDataProvider may provide multiple capabilities - for example, most GETAll endpoints for Business object REST API services also allow fetching data for specific keys, and from an offset, on the same endpoint. However, on rare occasions authors might require different endpoints to support different fetch capabilities. A MultiServiceDataProvider can be used for this purpose.
Note:
When the label for the selected value(s) is not set via the 'value-option' component attribute, and fetchByKeys capability is available for the service / endpoint, a fetchByKeys call is made by the component. It is important that page authors provide an endpoint that provides a fast lookup for fetching data for a key. Refer to the capabilities property, and the fetchByKeys request transforms properties of the ServiceDataProvider2 docs. Also refer to fetchByKeys property below for details
It is important that page authors provide an endpoint that supports an offset based lookup for fetching data for a given offset and size. See fetchByOffset property below for details
Design Time Assumptions
At design time, a service author can identify different endpoints that provide the fetchByKeys and fetchByOffset capabilities, in addition to the current fetch all (fetchFirst capability). When there are different endpoints a page author must pick different endpoints for each (fetch) capability when configuring a variable of a type vb/MultiServiceDataProvider. It is common for the same REST endpoint to support multiple capabilities.
- for fetchByKeys
- For example, the same endpoint can fetch all territories and a set of territories that match a set of territory codes (fetchByKeys):
GET /fndTerritories? and /fndTerritories?q=TerritoryCode in ('US', 'AE')
- the same endpoint can be used to fetch all customers, or to fetch customers by specific keys using the same endpoint but different query parameters:
GET /customers and GET /customers?ids=cus-101,cus-103
.
- For example, the same endpoint can fetch all territories and a set of territories that match a set of territory codes (fetchByKeys):
- for fetchByOffest
-
- an Oracle Cloud application endpoint can fetch all territories, and territories at a given offset - GET
/fndTerritories
and/fndTerritories?offset=50&size=10
- an Oracle Cloud application endpoint can fetch all territories, and territories at a given offset - GET
-
Properties
A variable of the built-in type vb/MultiServiceDataProvider2 can be configured with the dataProviders
property using the following sub-properties.
dataProviders Sub-property | Type | Example | Description |
---|---|---|---|
fetchFirst | "vb/ServiceDataProvider2" |
where the resorucesListSDP looks like below
|
A MultiServiceDataProvider is needed only when more than one fetch capability needs to be configured. |
fetchByKeys | "vb/ServiceDataProvider2" |
where the resourceByKeySDP looks like below
|
A reference to the vb/ServiceDataProvider variable. |
fetchByOffset | "vb/ServiceDataProvider2" |
|
A reference to the vb/ServiceDataProvider variable. |
Behavior
A variable of type vb/MultiServiceDataProvider2 must have at least one fetch capability defined. Otherwise an error is flagged. When a fetchFirst capability is not defined, a no-op fetchFirst capability is used. The JET DataProvider contract requires a fetchFirst implementation to be provided. All fetch capabilities must point to a variable of type vb/ServiceDataProvider. A MultiServiceDataProvider cannot reference another MultiServiceDataProvider variable.
Usage: When a service provides unique endpoints for different fetch capabilities
When a service has unique endpoints for each fetch capability, we will require one variable of type 'vb/ServiceDataProvider2' per fetch API, and a variable of type 'vb/MultiServiceDataProvider2' variable that combines the individual ServiceDataProvider2 variables together. The list-of-values component will then bind to a variable of type vb/MultiServiceDataProvider.
Let's consider this third-party REST API that is used to get information about countries.
-
fetchFirst capability: to get a list of all countries and their info, where the alpha3Code is the primary key
-
service/endpoint: rest-service/getAllCountries
-
GET https://restcountries.eu/rest/v2/all
-
- fetchByKeys capability (with multi key lookup): to get a list of countries by their
three-letter alpha code
-
service/endpoint: rest-service/getCountriesByCodes
-
GET https://restcountries.eu/rest/v2/alpha?codes=usa;mex
-
In order for the list-of-values component to use the above endpoints, the design time will need to create three variables:
-
One vb/MultiServiceDataProvider2 variable that references two ServiceDataProvider variables, one for each fetch capability
-
Two vb/ServiceDataProvider2 variables
vb/MultiServiceDataProvider Configuration
At design time, a variable using this type will be created that looks like this:
1 {
2 "variables": {
3 "countriesMultiSDP": {
4 "type": "vb/MultiServiceDataProvider2",
5 "constructorParams": [
6 {
7 "dataProviders": {
8 "fetchFirst": "{{ $page.variables.allCountriesSDP.instance }}
9 "fetchByKeys": "{{ $page.variables.countriesByCodesSDP.instance }}"
10 }
11 }
12 ]
13 }
14 }
15 }
-
Line 3: countriesMultiSDP is a variable of type vb/MultiServiceDataProvider. This defines two properties: 'fetchFirst' and 'fetchByKeys'.
-
Line 7: The fetchFirst property allows the MultiServiceDataProvider to call fetchFirst() on the referenced ServiceDataProvider variable.
-
Line 8: The fetchByKeys property allows the MultiServiceDataProvider to call fetchByKeys() on the referenced ServiceDataProvider.
vb/ServiceDataProvider Variables Configuration
For the above use case, the referenced ServiceDataProvider variables will be configured as follows:
Configuration | Description |
---|---|
|
Line 3: defines the ServiceDataProvider2 variable with a fetchFirst capability.
Line 7: defines the endpoint to use the getAllCountries operation to fetch all countries. |
|
Line 4: defines the ServiceDataProvider2 variable that supports a fetchByKeys capability. Line 8: uses the getCountriesByCodes operation to fetch a list of countries by their codes. Line 10: a 'capabilities' property is added to ServiceDataProvider that has a 'fetchByKeys' property object. See next section for details.
Line 16: the 'mergeTransformOptions' property is set to a page function.
|
|
Line 17: function that fixes up the transform options that will be sent to the transform functions. Line 33: set a new 'codes' query parameter, whose value is a ';' separated list of country alpha codes. |
Configuring a JET Combo/Select at Design Time
-
One vb/MultiServiceDataProvider variable
-
Two vb/ServiceDataProvider variables
-
Line 2 points to a variable of type vb/MultiServiceDataProvider2.
1 <oj-combobox-one id="so11" value="{{ $variables.selectedActivities }}"
2 options="[[ $variables.countriesMultiSDP.instance ]]"
3 options-keys.label='[[ "name" ]]'
4 options-keys.value='[[ "alpha3Code" ]]'
5 </oj-combobox-one>
A distinct vb/ServiceDataProvider variable is needed for each unique service/endpoint.
Often authors want to provide different default filterCriterion, sortCriteria or uriParams, or even write different transforms for each capability. Isolating each capability to a unique SDP variable allows for this separation. Also, any of these individual vb/ServiceDataProvider variables might externalize its fetch, or allow an actionChain assign values to its properties directly via expressions, or allow a fireDataProviderEventAction reference the SDP variable directly. This is another reason to have have first class variables - making it easy for page authors to access them.
Usage: When a service provides unique endpoints for different fetch capabilities, but the fetchByKeys endpoint only supports a single-key-based lookup
In this use case, the service supports a fetchFirst capability that fetches all rows, and a fetchByKeys capability that returns a single row by its key. There is no endpoint that can return rows by multiple keys.
To understand this usecase further let's take the example of the sample ifixitfast service - and the incidents endpoints that is used to get information about incidents.
- fetchFirst capability: to get a list of all incidents for the selected technician,
- service/endpoint:
fixitfast-service/getIncidents
- GET
https://.../ifixitfaster/api/incidents?technician=hcr
- service/endpoint:
- fetchByKeys capability (with single key lookup): to get a single incident it its 'id'
- service/endpoint:
fixitfast-service/getIncident
- GET
https://.../ifixitfaster/api/incidents/inc-101
- service/endpoint:
In order for the lov component to use the above endpoints DT will need to create 3 variables:
- One vb/MultiServiceDataProvider variable that references two SDP variables, one for each fetch capability
- Two vb/ServiceDataProvider variables
vb/MultiServiceDataProvider Variable Configuration
The configuration for the vb/MultiServiceDataProvider variable is similar to the previous examples.
1 {
2 "variables": {
3 "countriesMultiSDP": {
4 "type": "vb/MultiServiceDataProvider2",
5 "constructorParams": [
6 {
7 "dataProviders": {
8 "fetchFirst": "{{ $page.variables.allIncidentsSDP.instance }}
9 "fetchByKeys": "{{ $page.variables.incidentsBySingleKeySDP.instance }}"
10 }
11 }
12 ]
13 }
14 }
15 }
vb/ServiceDataProvider Variables Configuration
For the previous use case, the referenced ServiceDataProvider2 variables will be configured as follows.
Configuration | Description |
---|---|
some-page.json
|
|
|
Line 4: defines the ServiceDataProvider variable with the fetchByKeys capability. The ServiceDataProvider variable is configured for an implicit fetch. Line 8: uses the getIncident operation to fetch a single incident by its id. Line 10: maps the 'id' key in the 'uriParameters'.
Line 14: a new 'capabilities' property is added to ServiceDataProvider that has a 'fetchByKeys' key object.
Notice that a 'mergeTransformOptions' property is not set.
|
|
Line 4: defines the ServiceDataProvider variable with a fetchByKeys capability.
Line 10: sets a mergeTransformOptions function.
|
|
mergeTransformOptions function |
|
The external fetch action chain is configured as follows. Line 4: the action chain used by the ServiceDataProvider2. Line 23: the RestAction, the chain calls to fetch a single incident by id. Line 28: the 'uriParams' property of the RestAction is set to the page variable "incidentId".
Line 31: the requestTransformFunction.query maps to a query transform function that substitutes the endpoint URL with the final id value. |
|
Query transform function |
Usage: When the same endpoint supports multiple fetch capabilities
Most list-of-value objects fall into this category. For example, to fetch both a list of territories and to fetch a subset of territories by their ids, the same endpoint is used:
-
fetchFirst capability:
-
service/endpoint: fa-crm-service/getTerritories
-
GET /fndTerritories?finder=EnabledFlagFinder;BindEnabledFlag=Y
-
-
fetchByKeys capability:
-
GET /fndTerritories?finder=EnabledFlagFinder;BindEnabledFlag=Y&q=TerritoryCode IN ('AE', 'AD', 'US')
-
In this case, a single SDP variable of type vb/ServiceDataProvider2 that multiplexes different fetch capabilities is the recommended approach. The SDP2 variable can then be used to bind to the list-of-values component.
Note:
It is recommended that service authors ensure that the service is configured to use the default Business object REST API transforms.vb/ServiceDataProvider2 Variables Configuration
The data returned by the service endpoint will look something like this:
{
"items": [
{
"TerritoryCode": "AE",
"AlternateTerritoryCode": "ar-AE",
"TerritoryShortName": "United Arab Emirates",
"CurrencyCode": "AED"
},
...
],
"count": 25,
"hasMore": false,
"limit": 25,
"offset": 0,
}
The ServiceDataProvider variables for the fetchFirst and fetchByKeys capabilities will be configured as follows
sample-page.html | Description |
---|---|
|
A finder query parameter is applied to all queries going against the endpoint. When no capabilities are set, the ServiceDataProvider2 variable is assumed to support a fetchFirst capability |
Configuring a JET Select-Single in Design Time
-
Line 1: the value is bound to a variable that is an array of selected TerritoryCode keys.
-
Line 2: the data attribute is bound to the SDP2 variable.
1 <oj-select-single id="so11" value="{{ $variables.selectedTerritories }}"
2 data="[[ $variables.territoriesSDPVar.instance ]]"
3 item-text='[[ "TerritoryShortName" ]]'
4 </oj-select-single>
Usage: When a service provides a fetchByKeys capability, and DataProvider.containsKeys is called
The containsKeys() method can be called by components bound to a ServiceDataProvider variable that supports the 'fetchByKeys' capability. The default implementation of containsKeys() will call fetchByKeys() and return a oj.ContainsKeysResult object as defined by the JET DataProvider contract.