JavaScript API Wrapper Class

Files

/engine/class.www-wrapper.js

Introduction

Main purpose of an API Wrapper is to make it easier to make API requests over HTTP to a system built on Wave Framework. API Wrapper class does everything for the developer without requiring the developer to learn the ins and outs of technical details about how to build an API request. Wave Framework comes with two separate API authentication methods, one more secure than the other, both which are handled by this Wrapper class. JavaScript API Wrapper does not support sending data in encrypted form or decrypting encrypted data from a response.

API Wrapper does a lot of thing for the developer and takes the web browser options into account, but there are still a couple of things that should be considered when using the Wrapper. It requires JSON support on the web browser for various functionality, such as for hash validations.

API Wrapper makes requests by default using XMLHttpRequest(), but not asynchronously. Asynchronous requests are also possible. Requests gather data from one of two places: Either directly as input or using an existing form on the page, latter of which allows for file uploads. JavaScript API Wrapper submits files using hidden iFrames.

This API Wrapper has been tested and must work with all modern web browsers. Wrapper should work without problems on latest versions of Google Chrome, Mozilla Firefox, Apple Safari, Opera and Internet Explorer.

API Wrapper can use all three methods of connecting to and authenticating with a server.:

JavaScript API Wrapper is slightly more limited than PHP API Wrapper. Main difference is that it is not possible to encrypt and decrypt data with JavaScript API Wrapper.

API Wrapper offers as much functionality as you would get over making API requests manually yourself, so it is recommended - in most cases - to make the API requests through the Wrapper. Though the API is simple enough that you can also make the requests without the Wrapper, but this is covered in API Documentation section.

Using JavaScript API Wrapper Class

One of the main things about using JavaScript API Wrapper is to use only one instance of it in your front-end. While you can create two Wrapper objects and use them at the same time, this can cause some parallel processing issues. It is best to use just a single object and send requests through there.

It is recommended to go through all of the API Documentation sections before using the API Wrapper. This document here covers details only specific to API Wrapper and not the details about other API keywords themselves.

JavaScript API Wrapper is stored as a file in '/engine/class.www-wrapper.js', but it is not dependent on anything else in the Filesystem and can be used independently. API Wrapper works in all modern browsers.

To use the API wrapper, you need to include the script. This is usually done by placing it in the head of the document (note that the 'src' value should point to the actual location where you have placed the script). Like this:

	
	<html>
		<head>
			...other headers...
			<script type="text/javascript" src="class.www-wrapper.js"></script>
			<script	type="text/javascript">
				...your script here inline or as a source...
			</script>
		</head>
		<body>
			...my page...
		</body>
	</html>
	

When Wrapper object is created it requires just a single parameter: the HTTP address of the API. To create a Wrapper object you can do the following:

	
	// This creates local API connection on the same server the framework itself is set up
	var WWW=new WWW_Wrapper('json.api');
	

Note that you can face cross-domain AJAX issues if you define a full API URL that is set up on a different server than where the web system is running. As an alternative you can use PHP API Wrapper to easily make API requests to a different server if you cannot get cross-domain requests working.

JavaScript API wrapper is functionally similar to PHP wrapper, but it does not support data encryption and decryption (this should be handled by PHP due to security). It also handles file uploads a little differently compared to PHP.

API Wrapper takes the same type of data as API itself does, every API related parameter or setting is defined by array key with 'wave' prefixes of 'www-'. A method setInput() is used to send data to API Wrapper. It is possible to send an array, or a key/value pair to this method.

All native API parameters that you can use are detailed at API Documentation Input and Output section. To get the overview of API-specific keywords about API validation, then you should consult with that document.

There are also some API Wrapper specific parameters that you can send. These variables are never actually sent to API (they won't arrive in Wave Framework API controllers) and they are only used by Wrapper:

Please refer to Input and Output API Documentation to see the rest of the Wave Framework API flags and their description.

It is also important to note that you do not need to send every flag every time you use the Wrapper object to make requests. Wrapper will internally store a number of those settings and you can simply send what has changed in the subsequent requests. These flags will be used on subsequent requests when the same object is used even though they are not defined in the request specifically:

In case you need to reset these settings, then you can reset them one by one individually (which overwrites the previous values) or call clearInput(true) method.

For example, a simple command would be done this way:

	
	WWW.setInput({
		'www-command':'example-get'
	});
	// This is returned only for non-asynchronous requests, otherwise you have to use callbacks
	var result=WWW.sendRequest();
	

It is also possible to make a request with the sendRequest so that you send all or additional input parameters in the same request, like this:

	
	var result=WWW.sendRequest({
		'www-command':'example-get'
	});
	

To make a request that will execute a callback method, you can do the following:

	
	function myTest(data){
		alert(data['name']);
	}
	WWW.setInput({
		'www-command':'example-get',
		'www-true-callback':'myTest'
	});
	WWW.sendRequest();
	

It is also possible to define a anonymous function (also known as anonymous function) as the callback method, like this:

	
	WWW.setInput({
		'www-command':'example-get',
		'www-true-callback':function(data){
			alert(data['name']);
		}
	});
	WWW.sendRequest();
	

It is also possible to read the log of API Wrapper and see exactly what it did to make that request happen. You can print out the log like this:

	
	alert(WWW.returnLog("\n"));
	

API of WWW Framework has a lot of private profile validation options which you can read more about in other parts of API documentation, but for example, to create an API token and you already have the profile name and profile secret key, then you can do the following:

	
	WWW.setInput({
		'www-profile':'custom-profile',
		'www-secret-key':'my-secret-key',
		'www-true-callback':'assignToken',
		'www-command':'www-create-session'
	});
	var result=WWW.sendRequest();
	if(result){
		var token=result['www-token'];
	}
	

And you can make requests when you have the token, like this:

	
	WWW.setInput({
		'www-profile':'custom-profile',
		'www-secret-key':'my-secret-key',
		'www-token':token,
		'www-command':'example-get'
	});
	var result=WWW.sendRequest();
	

It is important to note that you don't necessarily have to define the secret key and token after you have already defined them, unless you have used $this->clearInput(true) method call. API Wrapper keeps in mind the last known secret key, API profile name and token. This would have worked too:

			
	WWW.setInput({
		'www-command':'example-get'
	});
	var result=WWW.sendRequest();
	

If returned result is 'false', then the request has failed. You should then look at the log, which details the reason for failure. Last error message is stored as $www->errorMessage and $www-responseCode. What each error code means, take a look at Response Codes documentation.

Also it is possible to get information about your currently used session token. If you have generated a token with Wrapper and you do not know what the token itself is, then you can get the currently active token with getToken() request, like this:

	
	var token=WWW.getToken();
	

JavaScript API Wrapper Class Parameters

var apiAddress=document.baseURI+'json.api'

This is the address and URL of the API that the Wrapper will connect to. The API address must be for Wave Framework API. This value is set either in object creation or when setting 'www-address' input variable.

var apiLanguage=document.documentElement.lang

This holds the current language of the API, it can be useful if the API commands return language-specific responses and translations from the API. This variable is set by sending 'www-language' input variable.

var apiState

This holds information about current API state, such as profile name, secret key and various API-related flags for callbacks, asynchronous status and more. This variable is passed around per each API call.

var errorMessage=false

This variable holds the last known error message returned from the API.

var responseCode=false

This variable holds the last known response code returned from the API.

var inputData=new Object()

Input data is a variable that stores all the plain-text input sent with the API request, it's a key-value pair of variables and their values for the API.

var log=new Array()

This is an array that gathers log information about the requests made through the API that can be used for debugging purposes should something go wrong.

var userAgent='WWWFramework/3.0.0 (JavaScript)'

This is the user-agent string of the API Wrapper. At the moment it is not possible to set custom headers with AJAX requests, so this variable is unused in the class and only defined for future purpose.

var getLimit=2048

This is the GET string maximum length. Most servers should easily be able to deal with 2048 bytes of request string length, but this value can be changed by submitting a different length with 'www-get-length' input value.

var resetLog=true

If this value is set, then API log will be reset after each API request. This value can be sent with 'www-reset-log' keyword sent to Wrapper.

JavaScript API Wrapper Class Methods

function WWW_Wrapper(address,language)

Wrapper object creation requires an 'address', which is the address that Wrapper will make API requests to. If this is not defined, then 'address' assumes that the system it makes requests to is the same where the API is loaded from. 'language' is a language keyword from the system that API makes a connection with and is used whenever language-specific results are returned from API.

this.returnLog=function(implode)

This method returns current log of the API wrapper. If 'implode' is set, then the value of 'implode' is used as a character to implode the log with. Otherwise the log is returned as an array.

this.getToken=function()

This method returns currently used token, if one exists. This can be stored for subsequent requests with Wrapper (or manually over HTTP).

this.clearLog=function()

This method clears the API log. This method can be called manually or is called automatically if log is assigned to be reset with each new API request made by the object.

this.setInput=function(input,value)

This method is used to set an input value in the API Wrapper. 'input' is the key to set and 'value' is the value of the input key. 'input' can also be an array, in which case multiple input values will be set in the same call. This method calls private inputSetter() function that checks the input value for any internal flags that might not actually be sent as an input to the API.

var inputSetter=function(input,value)

This is a helper function that setInput() method uses to actually assign 'value' to the 'input' keyword. A lot of the keywords set carry additional functionality that may entirely be API Wrapper specific. This method also creates a log entry for any value that is changed or set.

A lot of the values set by inputSetter() method are defined above in 'Using JavaScript API Wrapper Class' section.

this.setForm=function(formId)

This method sets the form ID that is used to fetch input data from. This form can be used for uploading files with JavaScript API Wrapper or making it easy to send large form-based requests to API over AJAX.

this.clearForm=function()

This method unsets the attached form from the API request.

this.clearInput=function(reset)

This method resets the state of API. It is called after each API request with 'reset' set to false. To entirely reset the state of API 'reset' should be set to true and this will reset everything except the log file.

this.sendRequest=function(variables,formId)

This method executes the API request by building the request based on set input data and set forms and sending it to API using XmlHttpRequest() or through hidden iFrame forms. It also builds all validations as well as validates the returned response from the server and calls callback functions, if they are set. It is possible to send input variables directly with a single call by supplying the 'variable' array. Form ID can also be sent with the request directly.

This method builds the request variables based on requirements of Wave Framework and includes validation and authentication for API profiles.

If form ID is set, then the request is made to a hidden iFrame, otherwise the request is made with XmlHttpRequest() and either asynchronously or not. Request is made with POST if the GET length request URL is longer than 2048 characters (or another length, if different GET length is set in API Wrapper).

After the request is made, this method sends the data to parseResult() method.

var parseResult=function(resultData,thisInputData,thisApiState)

JavaScript API Wrapper handles asynchronous requests and all of request callbacks, which allows to make multiple API requests at the same time or in sequence. This method validates the response data, if validation is requested and executes set callbacks with the results. 'resultData' is the response from the API call, 'thisInputData' is the original input sent to the request and 'thisApiState' is the API Wrapper state at the time of the request.

It also attempts to unserialize the response from API and return it as a JavaScript object, in case it is in JSON format. Other formats are not supported by JavaScript API Wrapper.

Method will also send the response to success, failure and error callback functions with the entire response, if these callbacks are defined.

In case new API profile session was created, then it also assigns the API token for other API requests.

var errorHandler=function(thisInputData,thisResponseCode,thisErrorMessage,thisErrorCallback)

Error handler method is used for cases where the API response is neither success or failure, but an actual error that should not happen. It adds a log entry about the error as well as calls error callback method. 'thisInputData' is the data that was input, 'thisResponseCode' is the response code from the API, 'thisErrorMessage' is the error message of the api and 'thisErrorCallback' is the callback method that is used.

var clone=function(object)

This helper method is used to clone one JavaScript object to another 'object' is the JavaScript object to be converted.

var validationHash=function(validationData,postFix)

This method is used to build an input data validation hash string for authenticating API requests. The entire input array of 'validationData' is serialized and hashed with SHA-1 and a salt string set in 'postFix'. This is used for all API requests where input has to be validated.

var ksortArray=function(data)

This is a helper function used by validationHash() function to serialize an array recursively. It applies ksort() to main method as well as to all sub-arrays. 'data' is the array or object to be sorted.

var buildRequestData=function(data)

This is a method that is similar to PHP http_build_query() function. It builds a GET request string of input variables set in 'data'.

var subRequestData=function(key,value)

This is a helper function for buildRequestData() method, it converts between different ways data is represented in a GET request string.

var encodeValue=function(data)

This helper method converts certain characters into their suitable form that would be accepted and same as in PHP. This is a modified version of encodeURIComponent() function. 'data' is the string to be converted.

var ksort=function(object)

This is a JavaScript method that works similarly to PHP's ksort() function and applies to JavaScript objects. 'object' is the object to be sorted.

var sha1=function(msg)

This is a JavaScript equivalent of PHP's sha1() function. It calculates a hash string from 'msg' string.