...
When you import the stub into a Javascript environment (the Carbon server or a web page shown in a browser), a global object called 'services' is created with a property as the name of the service. That is, for a service named "helloworld", importing the helloworld stub will create a global object called "services". By manipulating the properties and calling the methods of this object, messages can be sent to an endpoint and the responses can be received.
Invoke Service Operations
The 'services' global object has the property 'service name' and that property has attributes such as operations exposed by that web service, end point details etc. Format of the global object 'services' for 'helloWorld' service is as follows.
...
Code Block | ||
---|---|---|
| ||
try { var theResponse = services["admin/helloWorld"].operations["hello"]; } catch (e) { alert("Danger Robinson! " + e); } |
Setting Endpoints and Endpoint Addresses
The global object corresponding to a service has a property and two methods which help you determine the binding to use in order to invoke the service:
...
Code Block | ||
---|---|---|
| ||
// choose an endpoint type services["serviceName"].$.endpoint = "HTTPEndpoint"; // record where the messages were supposed to go log("Original destination: " + services["serviceName"].$.getAddress("HTTPEndpoint")); // redirect the messages to a different port for logging/debugging purposes. services["serviceName"].$.setAddress("HTTPEndpoint", "http://localhost:12345/services/myService"); |
Asynchronous Invocation
Because Web Services often involve communicating with services from diverse locations, it is a best-practice to make the call asynchronously. In the browser, this prevents the UI from blocking and becoming unresponsive. It offers better performance because you can invoke several operations in parallel rather than waiting for one to complete before starting the next. Asynchronous programming can be a bit more complicated than regular synchronous calling, but the benefits are usually well worth the additional complexity. The stubs support asynchronous calling through the addition of two properties (callback, onError) on the method objects:
...
- error.code: when the binding is SOAP, the error.code will be the QName corresponding to the <code> element.
- error.reason: a human readable error message. When the binding is SOAP, the error.reason corresponds to the <reason> element.
- error.detail: additional information about the failure, for instance a stack trace. When the binding is SOAP, the error.detail corresponds to the <detail> element.
Authentication
A service requiring username/password authentication can be accessed by setting the username and password annotations on the 'services' global object prior to calling an operation:
...
Code Block | ||
---|---|---|
| ||
services["helloworld"].$.username = "joey"; services["helloworld"].$.password = "fahr451!"; var helloWorld = services["admin/helloWorld"].operations["hello"]; var payload = null; helloWorld.callback = function(payload) { var responseXML = WSRequest.util._serializeToString(payload); }; helloWorld.onError = handleError; helloWorld(payload); function handleError(error) { log (console, "Fault: " + error.reason + "\n\n" + error.detail); }; |
Using Stubs in Web Pages
In order to use the stub in a Web page, you must import it using a normal script import statement:
...
Code Block | ||
---|---|---|
| ||
<script type="text/javascript;e4x=1" src="?stub&lang=e4x"></script> |
Using Stubs in Services
To access one Javascript service from another, first make a copy of the stub that you wish to use (for now use "?stub&lang=e4x&localhost=true", so you can get direct access to XML results as native E4X objects), and place it in the {servicename}.resources folder. Then you can include it in the Javascript for your service as follows:
...
File paths in system.include are interpreted relative to the .resources folder for that service. The effect of the include is as if you had copied and pasted the text of the stub directly into the Javascript for the service.
Automatic Type Conversions
When a service returns a value (described by one of the XML Schema built-in types), the stub converts that value into a native Javascript type as follows:
XML Schema type | JavaScript type |
---|---|
E4X XML object | |
string | |
string | |
boolean | |
number | |
Date(yyyy, mm, dd, 0:00:00, tz) | |
Date(yyyy, mm, dd, hh:mm:ss, tz) | |
string | |
number | |
Number (in milliseconds) | |
xs:ENTITIES | Array of strings |
xs:ENTITY | string |
number | |
Date(1970, 1, dd, 0:00:00, tz) | |
Date(1970, mm, 1, 0:00:00, tz) | |
Date(1970, mm, dd, 0:00:00, tz) | |
Date(yyyy, 1, 1, 0:00:00, tz) | |
Date (yyyy, mm, 1, 0:00:00, tz) | |
string | |
xs:ID | string |
xs:IDREF | string |
xs:IDREFS | Array of strings |
number | |
number | |
string | |
number | |
xs:Name | string |
xs:NCName | string |
number | |
xs:NMTOKEN | string |
xs:NMTOKENS | Array of strings |
number | |
r | number |
string | |
xs:NOTATION | string |
number | |
xs:QName | E4X QName object consisting of name, prefix, local-name, namespace-uri. (Note that DOM stubs don't support QNames yet.) |
number | |
string | |
Date(1970, 1, 1 hh:mm:ss, tz) | |
string | |
number | |
number | |
number | |
number |
Utility Functions
The 'services' global object also exposes some utility functions that can be used to further manipulate data types:
...