This topic is for developers who want to build web applications using FME Server Web Services API. This topic contains code for common requests with FME Server Web Services API.
This tutorial for JavaScript, but the same concept can be applied to other programming languages.
Please note that the sample code provided is intended for demonstration purposes only:
Web Services API Demo - JavaScript
For demonstration purposes a sample JavaScript web application has been created to illustrate many of the common FME Web Service API concepts with sample code. The sample application must be run on the machine FME Server is hosted on. When the command line application opened in a web browser, JavaScript will render a popup containing instructions.
Note: Our demo also takes advantage of our REST API. The reason behind this will become obvious as you read on.
Web services are run on workspaces which reside in repositories. Futhermore, each workspace can be setup to have a different subset of published parameters and web services available. However, the Web Services API does not provide any means of determining the available repositories, workspaces, and their respective published parameters and serives available.
Developers can either:
Require the application user to know in advance the service, repository and workspace names, refusing any invalid requests
Use one of the other APIs available to determine the information
Of the available APIs, the REST API is the most compatible because:
REST also accepts HTTP requests
Replies in the same choice of formats (html, xml, json)
Our REST API supports Working with Repositories, Working with Workspaces, and Working with Jobs. Although not listed in the REST tutorial, (but included in our demo), REST can determine the available services for a given workspace.
For the purpose of this tutorial, we will be creating a popup window that interacts with the user.
The first step with any FME REST API call using javascript is to create an ajax session.
var httpRequest;
if (window.XMLHttpRequest)
{
httpRequest = new XMLHttpRequest();
}
else
{
// for older versions of Internet Explorer
httpRequest = new ActiveXObject("MSXML2.XMLHTTP.3.0");
}
httpRequest.open(method, url, true);
Once the connection has been established, setup the response handler.
httpRequest.onreadystatechange = function()
{
if (httpRequest.readyState == 4)
{
if (httpRequest.status == 200)
{
// code to deal with response goes here
}
else
{
// an error occurred - varies depending on request (see API docs)
alert("An error occurred");
}
}
}
A very important step is ensure you send a message after setting the reponse handler so that a response will be received.
// null for certain requests
httpRequest.send(parameters);
How to list available services
Listing the services available for a workspace can be done using REST and knowing the URI to the workspace (which can be generated from the repository and workspace name).
httpRequest.open("GET", workspaceURI + "/.json", true);
httpRequest.onreadystatechange = function()
{
if (httpRequest.readyState == 4)
{
if (httpRequest.status == 200)
{
var reply = eval("(" + httpRequest.responseText + ")");
// generate an output message based on the response received
var reply = eval("(" + httpRequest.responseText + ")");
var outputDoc = "Services:";
// check that there are services available for this workspace
if (typeof(reply.serviceResponse.workspace.services.service) != 'undefined')
{
var services = reply.serviceResponse.workspace.services.service;
outputDoc += dropdownHTML('service', "window.opener.createForm()", services);
}
else
{
outputDoc += "No Services Available<br/>";
}
}
else
{
println("Error");
}
}
}
httpRequest.send(null);
Running the Web Service
To run the web service, we can send an HTTP request to the server.
For the purpose of this example, we will create a form using JavaScript and send the request via an HTML form submit.
outputDoc += "<form name='serviceForm' method='post' action='"
+ workspaceService.service.urlPattern + "/"
+ workspaceService.repository.name + "/"
+ workspaceService.workspace.name + "'>";
// here we can add any parameters and tm_directives
outputDoc += "<input type='submit' value='Run'/>";
outputDoc += "</form>";
Working with Transformation Manager Directives
Transformation Manager Directives are settings that can be applied to all services. These settings range in complexity from adding a description to scheduling the service to run at a later date. A list of TM directives can be found here
For our example, we set a high value for the priority of this job, in order to tell the FME Server to execute it before other tasks. This is not necessary but just done to illustrate how to set directives.
outputDoc += "<input type='hidden' name='tm_priority' value='80'>";
Working with Published Parameters
Through REST, we can easily obtain a list of published parameters and their respective input types.
Furthermore, we can create place each published parameter as a field in the form. Based on the response received from the REST call, we can determine information regarding each published parameter, and provide a user-friendly interface with labels, dropdown menus, and text fields.
parameters = workspaceService.workspace.parameters.parameter;
// if parameters is not an array, it's a single parameter
if (parameters.length == null)
{
parameters = workspaceService.workspace.parameters;
}
// add each parameter as a field in the form
for (var i in parameters)
{
var parameter = parameters[i];
outputDoc += "<label>" + parameter.description + "</label>";
// use <select> for single and multi-choice options
if (parameter.optionsType == "MULTICHOICE_CONFIG"
|| parameter.optionsType == "SINGLECHOICE_CONFIG")
{
// name based on response
outputDoc += "<select name='" + parameter.name + "'";
// allow multiple for multi-choice
if (parameter.optionsType == "MULTICHOICE_CONFIG")
{
outputDoc += " multiple='true' ";
}
outputDoc += ">";
// add each option
var options = parameter.options.option;
for (var j in options)
{
var value = options[j].value;
// use a display alias if possible
var display = (typeof(options[j].displayAlias) == "undefined")
? options[j].value
: options[j].displayAlias;
outputDoc += "<option value='" + value + "'";
// select the default value
if (parameter.defaultValue == value)
{
outputDoc += " selected='selected' ";
}
outputDoc += ">" + display + "</option>";
}
outputDoc += "</select>";
}
else
{
// for everything else, default to a text field
outputDoc += "<input type='text' size='50' name='"
+ parameter.name + "' value='" + parameter.defaultValue + "'>"
}
outputDoc += "<br/>";
}
Handling Responses
The format received will vary depending on the service used. XML, json, and html can be parsed and/or displayed. Any other format should be saved or run in another application (ie. Google Earth for .kmz files).
Since our demo created a form submission, the web browser will deal with the response based on the MIME-type.