Application Builder Cloud Service 17.1.3 release allows users to expose an external web service as a business object by creating a custom business object provider (BOP). In this blog we will create a Business object leveraging the REST APIs provided by GitHub using the custom BOP template that comes out of the box.

 

Evaluate the REST resource

 

GitHub exposes a set of REST APIs to fetch information regarding the user’s account.The complete list of all resources that can be fetched and the authentication schemes available can be seen here https://developer.github.com/v3/

For the purposes of this blog I have chosen https://api.github.com/users/shraybansal/repos to fetch the repositories information for the user shraybansal, whose account consists of two public test repositories.  If the user provides the Basic Auth credentials during authentication, then the REST request fetches information regarding private and public repositories associated with the authenticated user. Note that the REST API only fetches information of public repositories the user is associated with if no credentials are provided.

 

Even though GitHub supports Cross Origin Resource Sharing (CORS) and allows AJAX requests from all origins, an important detail to note is that in this blog we have leveraged the BOP Authenticator which implicitly takes care of the CORS request made through BOP. If BOP Authenticator is not leveraged during configuration then CORS will have to be enabled on the server to allow AJAX requests from the ABCS instance. Moreover, the REST APIs should be SSL enabled (https).

 

To begin, invoke your REST endpoint in a REST client to evaluate the fields that you require in your Business Object. I have used Postman, which provides a Chrome plugin, to invoke the GET request for the GitHub repository resource and selected id, repo_name and git_url to represent fields in the ABCS business object.

 

Field

Data Type

Description

id

Number

Id of the repository

repo_name

String

Name of the repository

git_url

String

The URL to access the repository

 

 

Configure showcase BOP Provider

 

In the Extensions section of the Application Settings create a new BOP Extension and give the package name as com.test

Note: In case any other package name is used then replace com.test references used in this blog with the package name provided.

 

25.PNG

Click on Template and choose the showcase BOP provided with the ABCS instance. The showcase BOP is an example of how the Application Builder APIs are being used in the BOP configuration through Employee and Department entities.

This action creates the files required for configuring a BOP and arranges the files in a defined structure in the Resource Browser.

 

 

Modify the Entity Provider

 

To add the entity definition we will have to include the github repository entity to the existing entity definitions in the MyCustomEntityProvider.js file

In the existing code add the call to the _createGitHub method just before the _createDepartment method.

 

var github = this._createGitHub();

 

Add the github variable to the _entities array.

 

this._entities = [github, employee, department];

 

Define the GITHUB_ID variable and add the implementation of the _createGitHub entity in the code just before the _createEmployee method.

 

MyCustomEntityProvider.GITHUB_ID = 'com.test.github';
MyCustomEntityProvider.prototype._createGitHub = function() {
        var id = DataModelFactory.createProperty({
            id: 'id',
            name: 'ID',
            type: PropertyType.KEY
        });
        var repo_name = DataModelFactory.createProperty({
            id: 'name',
            name: 'repo_name',
            type: PropertyType.TEXT
        });
        var git_url = DataModelFactory.createProperty({
            id: 'git_url',
            name: 'git_url',
            type: PropertyType.TEXT
        });
        return DataModelFactory.createEntity({
            id: MyCustomEntityProvider.GITHUB_ID,
            singularName: 'GitHub Detail',
            pluralName: 'GitHub Details',
            description: 'BO representing details of GitHub Repo of the user',
            properties: [id, repo_name, git_url]
        });
    }; 

The code should look like this in the Resource browser

Click on Save before proceeding.

 

Create the implementation file

 

Create a Github.js file under the js directory.This file will hold the implementation of the READ operation which will be defined in the operations provider.

 

   

Add the implementation code to the file. This code is similar to the Employee and Department javascript files.

 

define([
    'operation/js/api/OperationResult'
], function (
        OperationResult
    ) {
    'use strict';
    var Github = function() {
    };
  
    Github.getRepos = function(url, authenticator, operationData) {
       var ajaxObj = {
            method: 'GET',
            url: url,
            dataType: 'json'
        }; 
          
    // Include REST call here which performs the real operation retrieving your Github data
  var self = this;
        return new Promise(function (fulfil, reject) {
         authenticator.invoke( ajaxObj ).then(function (response) {
                var arr = Github._parseDetails(response);
                return fulfil(OperationResult.success(arr));
            });
        });
  };
     Github._parseDetails = function (response) {
        var res = [];
        var data = response.getData();
        data.forEach(function(items) {
            res.push(items);
        });
        return res;
    };
    return Github;
});

The code in the Github.js file should look like this:

Click on Save before proceeding.

 

Modify the Operations Provider

 

The next step is to modify the operations provider MyCustomOperationProvider.js to define the operations allowed on the github entity.For simplicity sake we will add just the READ operation in the MyCustomOperationProvider.js file

Add the BOPAuthenticators and Resource APIs in the define block along with the reference to the Github javascript file created in the previous step to the array of dependencies

'bop/js/api/operation/BOPAuthenticators',  
 'bop/js/api/resource/Resource',
  'com.test/js/Github'

 

The define block should look like this:

 

The dependencies will be passed to the definition function as function arguments, listed in the same order as the order in the dependency array. The function is called to define the module once all dependencies have loaded.

function (
        BOPAuthenticators,
        Resource,
        OperationBuilder,
        OperationInput,
        Pagination,
        Operation,
        Department,
        Employee,
        Github 
    ) 

 

Add the dependencies parameter as the argument in the function that is referenced by MyCustomOperationProvider variable. The dependencies parameter is a required attribute in the authenticator implementation.

var MyCustomOperationProvider = function(dependencies)

 

Declare _resources array variable and the _authenticator, which holds the instance of the default authenticator for invoking rest services returned by the getDefault method of BOPAuthenticators, in addition to the _operations array

var self = this;
this._resources = [];
this._authenticator = BOPAuthenticators.getDefault(dependencies, {

            getResources: function() {
                return self._resources;
            }
   });

 

Add _initForGithub() call just before the _initForEmployees() method

After the additions the function would resemble

 

var MyCustomOperationProvider = function(dependencies) {
       this._operations = [];
       var self = this;
       this._resources = [];
        this._authenticator = BOPAuthenticators.getDefault(dependencies, {
            getResources: function() {
 return self._resources;
            }
        });
        this._initForGitHub();
        this._initForEmployee();
        this._initForDepartment();
    };

 

Define the GITHUB_ID variable, which should be the same as defined in the MyCustomEntityProvider.js.

Add method getAuthenticator and associate a function which returns an instance of the _authenticator variable

 

MyCustomOperationProvider.GITHUB_ID = 'com.test.github';
MyCustomOperationProvider.prototype.getAuthenticator = function() {

        return this._authenticator;
    };


After the modifications the code should look like this:

 

 

Add the method _initForGithub that internally calls _getAllRepos method, which associates a function that returns an Operation instance based on the current builder configuration provided by the user. The operation type Operation.Type.READ_MANY is leveraged for retrieving collection data and is available for example when client drops the Table into an empty page.

Moreover, we will also add the list of resources to be whitelisted that are exposed by this BOP in the _getAllRepos method.

 

MyCustomOperationProvider.prototype._initForGitHub = function() {
        var github = Abcs.Entities().findById(MyCustomOperationProvider.GITHUB_ID);
        if (github) {
            this._operations.push(this._getAllRepos(github));
        }
    };
  
   MyCustomOperationProvider.prototype._getAllRepos = function(github) {  
                var self = this;  
                var url = 'https://api.github.com/users/shraybansal/repos';  
        this._resources.push(  
            Resource.create({  
                id : 'github.fetch',  
                template : url,  
                entity : MyCustomOperationProvider.GITHUB_ID  
            })  
        );  
       
        return new OperationBuilder({  
            name: 'Get all Repos',  
            type: Operation.Type.READ_MANY,  
            performs: function(operationData) {  
                return Promise.resolve(Github.getRepos(url, self.getAuthenticator(), operationData));  
            }  
        }).description('Fetch all registered employees with all relevant information.').  
            takes(new OperationInput({  
                entity: github  
            })).  
            returns(github).  
            build();  
    };  

 

Click on Save Changes. After adding the two methods the code should look like this:

 

 

Modify the manifest.json file

 

We will now modify the manifest.json file to include the GitHub.js file to the runtime list of resources.

"resources": [
            "js/Department.js",
            "js/Employee.js",
            "js/Github.js",
            "js/MyCustomConditionVisitor.js",
            "js/MyCustomEntityProvider.js",
            "js/MyCustomOperationProvider.js"                          
        ]

 

The manifest.json file should look like this

 

Click on Save Changes and Reload the extension to complete the BOP configuration process.

 

Create Business Object

 

Navigate to Business Objects by going through the Menu and clicking on the Data Designer.

 

    

 

Click on the Business object from external service button and you will see your Business Object Provider (BOP) in the REST Services catalog. Select the BOP and click on Next.

Select the GitHub Detail Business Object and click on next.

 

Drag and drop git_url and repo_name to the Selected fields column. Click Next

Provide Basic Authentication credentials required for accessing the REST resource. Click Next.

 

22.PNG

Wait for the Changes Saved pop up to appear and click Finish.

Check the Data tab to see the data from the REST API

 

More information regarding the Business Object Provider can be seen through the documentation: Creating Business Objects

ABCS Extension APIs are documented here: JavaScript Extension Development API for Oracle Application Builder Cloud Service: Home

Subscribe to the ABCS Youtube channel: https://www.youtube.com/channel/UCFMTiIZAE6f3Ib91sY6Ms3g