JavaScript Web Service Annotations
Table of Contents
There are a number of annotations that you can insert into your JavaScript Mashup service that enrich the descriptions and tools generated by the mashup service. We encourage you to use these annotations liberally.
The WSO2 Mashup Server defines a set of properties that can be applied to the Global object, representing the service as a whole, or to individual functions. In JavaScript, functions are actually objects, and any object can have additional properties dynamically added to it. The set of common properties to set on an object is described below.
documentation Annotation
Documentation properties can be added either to the global object, or to individual function objects.
this.documentation = <div>The <b>simple</b> service has a single operation - <i>echo</i>.</div>;
echo.documentation = "The echo operation accepts a blob of XML and returns it to the caller unchanged."
function echo(xmlblob) {
return xmlblob;
}
The documentation can have either a string value, as shown in the echo.documentation property above, or it can have an XML.
The documentation property serves several purposes:
- It provides structured documentation within the service. While you could use JavaScript comments instead, using a documentation property to describe the service and its operations makes it possible to distinguish between comments describing the implementation, and comments documenting the behavior of the service, and to re-use the latter.
- The documentation for the service (this.documentation) appears in the WSDL as a top-level <documentation> element. The documentation for each operation (echo.documentation in the above example) appears as <documentation> elements on each Interface Operation.
- The documentation is displayed in the Try-it page.
- The documentation is also displayed in the ?doc page.
visible Annotation
By default, each function in a JavaScript service file is exposed as an operation. But often functions should be 'private', for the benefit of other functions and not an entry point that the author wishes to expose to a client. When the 'visible' property has the Boolean value false, the function is not exposed as an operation (e.g., it doesn't appear in the WSDL, Try-it, etc.)
function equals(lefthand, righthand)
{
return (lefthand == righthand && typeEquals(lefthand, righthand));
}
typeEquals.visible = false;
function typeEquals(lefthand, righthand)
{
return (typeof(lefthand) == typeof(righthand));
}
In the above example, there is an implicit "equals.visible = true;".
inputTypes and outputType Annotations
In a dynamically typed language like JavaScript, each argument or parameter passed into a function can have any type - it can be a string, a number, an object, whatever. But internally the function typically operates on a specific type of data. Maybe the function does a calculation, in which case the data must be in (or be converted to) numerical form.
JavaScript has rich facilities for converting datatypes - for instance if a function or operation expects a string, you can still pass it a number and JavaScript will convert the number to a string automatically. But there are limits to the ability of JavaScript to convert freely from one type to another - for instance converting a string to a number requires the programmer to specify how the conversion is done using the parseInt or parseFloat methods.
So despite the dynamic character of JavaScript, function parameters typically have a restricted set of types that they operate on, and the caller of the function needs to be aware of what types are allowed or preferred by the function. In JavaScript the programmer typically relies on examining the source code of the function - or of the comments or other human-readable documentation to determine what the types of parameters are.
When you are invoking a function remotely as a Web Service operation, examining the source code is less of an option. Having some machine-readable information about the type allows the client to provide some assistance (e.g., ?stub) to the programmer. In addition, the Web Service may be invoked from a language other than JavaScript, so even determining the JavaScript type might be somewhat irrelevant. A set of types that can be used across a variety of programming languages and environments is necessary. Just as XML provides a platform- and language-neutral way to format data, the XML Schema Language provides a way to define types. When you expose a Web Service, the type of the data, including both simple types like strings and numbers, and complex structures, can be described in XML Schema.
To address these issues, the Mashup Server provides the inputTypes annotation to allow the programmer to declare the expected type of input for each parameter of the operation as an XML Schema type. Although this isn't strictly necessary for the exposure of the operation (we'll map the parameters into an XML message regardless) having accurate type information makes for a much nicer experience for the user of your function. The outputType annotation serves a similar purpose for the return value.
The inputTypes property is a JavaScript object having a number of properties, which is equivalent to the number of parameters of the JavaScript function. The names of those properties are the names of the function parameters, and the value of the respective parameter is the intended XML Schema type (the 'xs:' namespace is assumed) for the function parameter.
countWords.inputTypes = {
{"content" : "string" },
{"ignoreHyphens" : "boolean" }
};
countWords.outputType = "integer";
function countWords(content, ignoreHyphens) {
.....
}
JavaScript (plus E4X) types map roughly into the XML Schema type system as follows:
| String | xs:string |
| Number | xs:float |
| Boolean | xs:boolean |
| Date | xs:dateTime |
| XML | xs:anyType |
In most cases you can be more precise, for instance using the xs:integer type instead of xs:float when only integer values are expected.
Other Annotations
For advanced usage, there are a number of other properties that can be used:
- this.targetNamespace : places the components of the description (WSDL 2.0, WSDL 1.1) in a specific namespace. By default, the targetNamespace is http://services.mashup.wso2.org/{service name}, which is of course not guaranteed to be unique.
- this.schemaTargetNamespace : sets the schema target namespace, which will be used as the namespace for any wrapper elements generated by the mashup server. By default the targetnamespace is http://services.mashup.wso2.org/{service name}?xsd.
- this.serviceName : exposes the service under an alternate name (in the WSDL, try-it, documentation, etc.) By default the serviceName is the name of the JavaScript file (minus the '.js'.)
- {function}.safe :indicates whether repeated calls to the operation cause side effects. For example, two calls to a 'bill me' operation would normally result in two charges, while two calls to a 'current activity' operation would not cause any harmful side-effects. The safe annotation maps to the wsdlx:safe attribute, and helps determine whether GET or POST is the most appropriate HTTP method to use.
- {function}.operationName : exposes the function as an operation under an alternate name (in the WSDL, try-it, documentation, etc.). By default, the operationName is the name of the function.