Accessing data via Jive Connects API

Version 2

    This tutorial introduces you to Jive Connects and how to use it. Through Jive Connects, your app can integrate back-end data from sources commonly found in the enterprise. For a more thorough look at Jive Connects, see Jive Connects API - Client Application Configuration and API Usage. If you're a Jive Admin, and would like to know how to setup Jive Connects, please read How a customer admin will set up a Jive Connects Service. Jive Connects includes a means for Jive community administrators to register services that should be accessible to apps in the community, as well as an API for apps to use when communicating with a service. Jive Connects extends the Open Social API (osapi.http) by providing the following solutions:

     

    • Managing the configuration of the base URL for each service so you only need to know the remote service instance that needs to be contacted.
    • Dealing with details of  authentication, including a requirement to securely manage user credentials for each service.

     

    Perform the following steps to use Jive Connects.

     

    Step 1. Require the Jive Connects feature

     

    To make your app require the Jive Connects feature, you need to include an appropriate <Require> element in the app.xml file, which describes the app as you can see in the following code example.

     

    <?xml version="1.0" encoding="UTF-8"?>
    <Module>
        <ModulePrefs title="Quotes Approval"
                    author="Jive Software"
               description="Manage pending sales quotations">
            <Require feature="jive-connects-v1">
                <Param name="alias:quotes|title:Quotes Service">jive:service://jivesoftware.com/quotes</Param>
            </Require>
            <Require feature="dynamic-height"/>
            <Require feature="osapi"/>
            <Require feature="views"/>
        </ModulePrefs>
        <Content view="home" type="html" href="quotes_home.html"/>
        <Content view="canvas" type="html" href="quotes_canvas.html"/>
    </Module>

     

    This example declares that your app should use the following features:

     

    • Jive Connects functionality version 1.0.0
    • Standard OpenSocial Gadget features for dynamically adjusting the height of a rendered application and views
    • OpenSocial API

     

    Step 2. Specify the services your app needs

     

    Within the Jive Connects <Require> element, you need to include a <Param> element with a unique alias for each service connection required by this app.

     

    <Require feature="jive-connects-v1">
        <Param name="alias:quotes|title:Quotes Service">jive:service://jivesoftware.com/quotes</Param>
    </Require>


    This code example uses the <Param> element to connect to the quotes service.

     

    Step 3. Give the service alias, title and tag

     

    You need to assign each parameter alias, title, and tag sub-elements.

     

    <Param name="alias:quotes|title:Quotes Service">com.jivesoftware.api.quotes</Param>

     


    The following values are identified in this parameter:

     

        • alias (quotes): This string identifier is used within the application to distinguish between different connections used in the same application.

        • title (Quotes Service): This string label identifies the connection in the configuration dialog.

        • tag (com.jivesoftware.api.quote): This string is used to select from among the configured services in this Jive instance. Consult the tag registry (add crossref) to figure out which tag to use.

     

    Step 4. Make requests to a service

     

    The following sample code makes an HTTP request to a service:

     

    function loadQuotes() {
        osapi.jive.connects.get({
            alias : 'quotes',
            headers : { 'Accept' : [ 'application/json' ] },
            href : '/quotes'
        }).execute(function(response) {
            if (response.error) {
                // Deal with an error scenario ...
            }
            else {
                // response.content is an array of information for each quote
                var html = "";
                $.each(response.content, function(index, quote) {
                    html += ... // Generate appropriate table row HTML for each quote
                });
                $("#table-body").html(html);
                gadgets.window.adjustHeight();
            }
        })
    }

     


    In this example, you can see several elements working together:

     

    • We want to use the Jive Connects connection with an alias "quotes" to perform this request.
    • Because the "format" parameter was omitted, the default value ("json") means we will be getting back a JavaScript object.
    • We know that our service supports a "/quotes" path (to be appended to the   service URL), which will return us a JSON array containing information   about each available sales quote.
    • We do not specify anything related to authentication of the individual user ... that is handled for us by Jive Connects.

     

    a. Use one of the following methods to perform an HTTP request against one of your configured connections.

    • osapi.jive.connects.delete(params) -- Return a request instance that will execute an HTTP DELETE call.
    • osapi.jive.connects.get(params) -- Return a request instance that will execute an HTTP GET call.
    • osapi.jive.connects.head(params) -- Return a request instance that will execute an HTTP HEAD call.
    • osapi.jive.connects.post(params) -- Return a request instance that will execute an HTTP POST call.
    • osapi.jive.connects.put(params) -- Return a request instance that will execute an HTTP PUT call.


    b. You can include the following params arguments in the calls described in the previous step.

    • alias -- The application defined alias for the Jive Connects connection this request should contact.  This parameter is required.
    • body -- The request body for this request (POST or PUT requests only).
    • format -- The format of the expected request body ("text" or "json").  In the latter case, the response content element will be converted into a JavaScript object for you.  Default value is "json".
    • headers -- A hash of HTTP headers (key is header name, value is an array of  String values for this header name) to add to this request.  By default,  no headers are added.
    • href -- The partial path to be  appended to the service URL.  If present, must be an empty string ("")  or a path starting with a slash ("/") character.  Default value is "".
    • params -- A hash of request parameters to be added to the absolute URL (key is  parameter name, value is an array of String values for this parameter  name).  By default, no request parameters are added.
    • refreshInterval -- The maximum number of seconds that the proxy server can cache the  response to this request.  By default, no caching takes place.

     

    c. You can deal with different response objects. To perform the actual I/O for this request, the request object returned from any of the methods described in the previous steps supports an execute() method.  This method accepts a callback parameter, which will receive as its parameter a response object with the following properties:

    • content -- The response body, if any, as a string if format is "text", or as a JavaScript object if format is "json".
    • error -- If an error occurred on this request, this property will exist, and will contain subproperties code (an error code) and message (an explanatory message describing the problem).  If this property does not exist, the request was successful.
    • headers -- A hash of HTTP headers (key is header name, value is an array of  String values for this header name) that were returned with this  response.
    • status -- The HTTP status code returned by the remote service.

     

    Step 5. Trigger collecting the user's credentials

     

    When an app's end user first installs an app, the user decides which service to use for each connection, but Jive does not ask for user credentials (for a service) until the users first accessed that service.  Instead, an HTTP  401 (Unauthorized) response is returned to the app, which signals the need for credentials. The app needs to trigger collecting the user credentials and reperforming the I/O request. You can see how it's done by expanding the example in the previous step:

     

    function loadQuotes() {
        osapi.jive.connects.get({
            alias : 'quotes',
            headers : { 'Accept' : [ 'application/json' ] },
            href : '/quotes'
        }).execute(function(response) {
            if (response.error) {
                if (response.error.code == 401) {
                    // Request Jive to configure (or reconfigure) credentials for this connection
                    osapi.jive.connects.reconfigure("quotes", response, function(feedback) {
                        loadQuotes(); // Resubmit the failed request
                }
                else {
                    // Deal with an error scenario ...
                }
            }
            else {
                // response.content is an array of information for each quote
                var html = "";
                $.each(response.content, function(index, quote) {
                    html += ... // Generate appropriate table row HTML for each quote
                });
                $("#table-body").html(html);
                gadgets.window.adjustHeight();
            }
        })
    }


    Note: If your service notifies you of an authentication problem using anything but an HTTP status code of 401, you need to adapt the conditional logic to trigger reconfiguration appropriately.

     

    Step 6. Improve performance by batching several requests together

     

    In Jive Connects, you can improve performance by batching several requests together, sending them to the Jive server all at once, and then getting responses back together.

     

    In the following example, assume you have accumulated an array of customerID values from the quotes being presented on a particular page, and you want to retrieve the associated customer information for those customers. In the case where a single customer might have more than one associated quote, you want to do this just once per individual customerID.

     

    // Return a request object to retrieve the specified customer by ID
    function loadCustomer(customerID) {
        return osapi.jive.connects.get({
            alias : 'quotes',
            headers : { 'Accept' : [ 'application/json' ] },
            href : '/customers/' + customerID
        });
    }

    // The customerIDs parameter is an array of unique customer ID values
    function loadCustomers(customerIDs) {
        var batch = osapi.newBatch();
        $.each(customerIDs, function(index, customerID) {
            // Add a batch request with access key "customerNNN" for each ID
            batch.add('customer' + customerID, loadCustomer(customerID));
        });
        // Perform all of the batched requests
        batch.execute(function(responses) {
            customers = [ ]; // "customers" is a global variable to receive the list
            // Iterate through each of the responses
            $.each(customerIDs, function(index, customerID) {
                var response = responses['customer' + customerID];
                // TODO - deal with response.error not being null
                customers.push(response.content);
            });
        });
    }


    In this example, we gather all of these requests into a single batch request to the Jive server and process them all at once.

     

    • The application accumulates a list of the unique customerID values it wants to acquire customer information for, and calls loadCustomers().
    • The loadCustomers() method creates a batch of request objects to all be performed together, one per customer, using theloadCustomer(customerID) function to create each of the requests.        
      • OpenSocial   batches identify the individual requests in a batch by a key that is   specified by the application.  Here, we are synthesizing keys like   "customerNNN", where "NNN" is the desired customer ID.
    • The batch is executed, and loadCustomers() iterates through the responses.  In the example above, we simply add   the customer information to a global array named "customers".

     

    Note: You can also "mix and match" the following request types in a single batch request:

      • Jive Connects API requests as illustrated above
      • Jive Core API requests (using the low level interface) to access information from your Jive instance
      • Any OpenSocial compatible request object, such as those returned by the osapi.http family of methods, or other OpenSocial functions that return request objects

    Step 7. Use a simple HTML templating approach to process information from remote services


    Sometimes, you may want to use a simple HTML templating approach to process information from remote services, instead of doing everything in JavaScript.  OpenSocial defines a feature called data pipelining to support this requirement, and Jive Connects supports similar capabilities. Jive Connects defines a template tag, <jive:ConnectsRequest>, that can be included in the HTML that defines your view.  This tag takes parameters that are similar to the osapi.jive.connects.get() method described earlier:

    • alias -- The application defined alias for the Jive Connects connection this request should contact.  This parameter is required.
    • href -- The partial path to be appended to the service URL.  If present,   must be an empty string ("") or a path starting with a slash ("/")   character.  Default value is "".
    • key -- A variable name that may be used later in your template to refer to the retrieved data.

     

    For example, you could embed the following code in the HTML of your view:

     

    <script type="text/os-data">
      <jive:ConnectsRequest key="customers" alias="quotes" href="/customers?offset=0&limit=5"/>
    </script>

     

    When the view is loaded, Jive ensures that a GET request to retrieve the specified data completes before the app starts executing. You can refer to the retrieved information using the key value specified later in the template.

     

    Step 8. Acquiring Information About Configured Services

     

    Most of the time, you don't need to know the details of which service the end user chooses at installation time to configure for each of the defined aliases.  Sometimes, though, it may be useful to know which service was selected.

     

    For example, when the application has been coded to adjust its behavior for two different versions of a service API, it needs to know the characteristics of  the service that was selected by the end user who installed the app. In this case, the app needs to define multiple tags in its app.xml configuration parameters, one per supported version of  the API.  When the app is installed, the user is offered any service (accessible by that user) that matches anyof the specified tags.  After the user makes the selection, the app needs to know which version of the API that particular service instance supports. The following example shows how to accomplish this.

     

    function loadConnection() {
        osapi.jive.connects.connection({
            alias : 'quotes'
        }).execute(function(connection) {
            // "connection" contains information about the configured connection for this alias
            // "connection.service.tags" is an array of the tags for the selected service
        });
    }


    Given access to the tags for the selected service, the app can adapt its behavior to the service the user selected upon installation.