Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EDT:Accessing a service"

(Accessing a third-party REST service)
 
(74 intermediate revisions by the same user not shown)
Line 1: Line 1:
This page contains code snippets for service access.  
+
You can access services from a Rich UI application. This page gives code examples. For additional information, see [[EDT:Resource Binding Services|Service bindings]]. <br>
  
You can access a service from a Rich UI application or (in the future) from code generated to Java.
+
== Accessing a dedicated service ==
  
'''''The details have changed in the days after version .081 Milestone 2.&nbsp;''''' The current details are outlined here:<br>
+
The simplest way to deploy a service written in EGL is to include it with the Rich UI application. The service in that case is known as a ''dedicated service''.<br><br>Assume that the service is named '''MyServiceType''' and the function of interest is named '''calculate'''. Here is a short example of the code necessary to access that service:  
  
::[[EDT:Resource Binding Services|Resource Binding for Services]]
+
<source lang="java">
 +
  call MyServiceType.calculate(myList)
 +
        returning to theCallBack
 +
        onException theExceptionHandler;
 +
</source>
  
= EDT version 0.80  =
+
<br>
  
In EDT version 0.80, your task is to code a '''call''' statement such as this one:
+
== Accessing an EGL service in either of its two forms  ==
 +
 
 +
If the logic for a given service is written in EGL, the logic might be accessed as a dedicated service or as an EGL REST-RPC service. In that second case, the service is deployed outside of the Rich UI application, typically on a different server.&nbsp; <br><br>Here is the simplest way to switch between accessing the identical EGL service logic in one way or another:<br>
 +
 
 +
#In your code, declare a binding variable and embed it in a '''call''' statement.
 +
#In the EGL deployment descriptor, define an entry.&nbsp; To switch between the two forms of the same service logic, you can vary the entry in the same deployment descriptor or, more likely, can reference a different deployment descriptor with a same-named entry. <br><br>
  
 
<source lang="java">
 
<source lang="java">
myBindingVar IHTTP? = Resources.getResource("binding:myResource");
+
/********************************************************
call MyInterface.myOperation() using myBindingVar
+
* Declare the binding variable                        *
returning to myCallBackFunction
+
********************************************************/
onException myExceptionHandler;
+
  myBinding IHttp? = Resources.getResource("binding:myBinding");
</source>
+
  
Your '''call''' statement typically has the following aspects:
+
/********************************************************
 +
* Call the service                                    *
 +
********************************************************/
 +
  call MyServiceType.calculate(myList)
 +
      using myBinding
 +
      returning to theCallBack
 +
      onException theExceptionHandler;
  
*Invokes a specific operation by referring either to a function in a Service type or to a function prototype in an Interface type.
+
/********************************************************
*Identifies service-access details by referring to a ''binding variable'', which is specific to a kind of service binding.&nbsp; That variable includes service-access details. You might have retrieved the details from the EGL deployment descriptor and then customized them; or you might have created the details from scratch, in your code.
+
* Example: create a new EGL project for                *
 +
* "Web 2.0 client application with services". Add the  *
 +
* the Service type shown next to the server package,  *
 +
* and add the Handler type to the client package.     *
 +
*                                                      *
 +
* Test the example in the Rich UI Preview tab          *
 +
* as follows:                                          *
 +
*                                                      *   
 +
*    1. Type valid input into the first text box;      *
 +
*      for example: 5, 12, 4.                         *
 +
*                                                      *
 +
*    2. Click '''Calculate'''.                        *
 +
********************************************************/
  
Otherwise, the '''call''' statement operates as follows:
+
/********************************************************
 +
* The file with a Service type                        *
 +
********************************************************/
 +
package server;
  
*In a Rich UI application, the statement causes an asynchronous invocation and identifies a callback function and an exception handler.
+
service MyServiceType
*Outside of Rich UI (in the future), the statement causes a synchronous invocation and does not identify a callback function or exception handler. If a returned value is expected, the statement identifies a variable to receive the returned value.<br>The synchronous '''call''' statement is now supported for accessing an IBM i called or service program, as described here: <br>&nbsp;&nbsp;&nbsp;&nbsp; [[EDT:Support for IBM i|Support for IBM i]].<br>
+
  
<br>
+
  // variables and constants can be here
 +
  function calculate(myScores Int[] in) returns(Decimal(4, 2))
 +
      numberOfScores, i, mySum Int;
 +
      numberOfScores = myScores.getSize();
  
== Accessing a dedicated service (version 0.80) ==
+
      for(i from 1 to numberOfScores)
 +
        mySum = myScores[i] + mySum;
 +
      end
  
You can reference a Service type... <source lang="java">
+
      return(mySum/numberOfScores);
myBindingVar HttpProxy;
+
  end
 +
end
  
call MyService.functionName(InField.text)
+
/********************************************************
  using myBindingVar
+
  * The file with a Handler type                        *
  returning to handleResponse
+
  ********************************************************/
onException serviceExceptionHandler;
+
package client;
</source>
+
  
...in one step: <source lang="java">
+
import server.MyServiceType;
call MyService.functionName(InField.text)
+
import org.eclipse.edt.rui.widgets.GridLayout;
using new HttpProxy
+
import org.eclipse.edt.rui.widgets.GridLayoutData;
returning to handleResponse
+
import org.eclipse.edt.rui.widgets.TextField;
onException serviceExceptionHandler;
+
import org.eclipse.edt.rui.widgets.TextLabel;
</source>
+
  
You can reference an Interface type...<source lang="java">
+
import dojo.widgets.DojoButton;
myBindingVar HttpProxy = new HttpProxy("server.MyService");
+
import dojo.widgets.DojoTextField;
  
call IMyService.functionName(InField.text)
+
handler MyHandler type RUIhandler{
using myBindingVar
+
      initialUI =[ui], onConstructionFunction = start,
returning to handleResponse
+
      cssFile = "css/MyClientAppWithService.css", title = "MyHandler"}
onException serviceExceptionHandler;
+
</source>
+
  
...in one step:<source lang="java">
+
  ui GridLayout{columns = 3, rows = 4, cellPadding = 4,
call IMyService.functionName(InField.text)
+
                children =[myResult, myButton, scores, codeLabel]};
using new HttpProxy("server.MyService")
+
returning to handleResponse
+
onException serviceExceptionHandler;
+
</source>
+
  
== Accessing an EGL REST-RPC service (version 0.80)  ==
+
  codeLabel TextLabel{layoutdata = new GridLayoutData{row = 2, column = 2},
 +
                      text = "Numbers:"};               
 +
 
 +
  scores TextField{layoutData = new GridLayoutData{row = 2, column = 3}};
  
<source lang="java">
+
  myButton DojoButton{layoutData =  
myBindingVar httpRest{@Resource {uri="binding:myEntry"}};
+
      new GridLayoutData{row = 4, column = 2},
call IMyServiceType.calculate(myList)
+
                        text = "Calculate", onClick ::= ui_onClick};
using myBindingVar
+
 
returning to theCallBack
+
  myResult DojoTextField{layoutData = new GridLayoutData{row = 4, column = 3}};
onException theExceptionHandler;
+
</source>
+
  
== Accessing a third-party REST service (version 0.80) ==
+
  function start()
  
<source lang="java">
+
  end
  
</source>
+
  function theExceptionHandler(exp AnyException in)
 +
 
 +
      SysLib.writeStdOut(exp.messageID + " " + exp.message);
  
== Accessing a called or service program on IBM i (version 0.80 or beyond) ==
+
      if(exp isa ServiceInvocationException)
 +
        SysLib.writeStdOut((exp as ServiceInvocationException).detail1);
 +
        SysLib.writeStdOut((exp as ServiceInvocationException).detail2);
 +
        SysLib.writeStdOut((exp as ServiceInvocationException).detail3);
 +
      end
 +
  end
  
See [[EDT:Support for IBM i|Support for IBM i]].
+
  function theCallBack(retResult decimal(4, 2) in)
 +
      myResult.text = retResult;
 +
  end
  
= EDT version .7  =
+
  function ui_onClick(event Event in)
  
In EDT version .7, your task follows this pattern:&nbsp; declare a service-access variable and use it in a call statement.  
+
      inputLength int = scores.text.length();
  
== Accessing a dedicated service (version .7)  ==
+
      myDelimiters string = ", ";
 +
      myPosition int = 1;
 +
      myToken string;
 +
      myList int[];
  
<source lang="java">
+
      while(myPosition < inputLength)
// 1. declare the service-access variable
+
        myToken = StringLib.getNextToken(scores.text, myPosition, myDelimiters);
myService MyServiceType?{@dedicatedService}
+
  
// 2. call the service
+
            if(myToken != null)
call myService.theFunction() returning to theCallBack
+
              myList.appendElement(myToken as int);
onException theExceptionHandler;
+
            end
 +
      end
  
/*
+
      /************ Service access statements ***************************/
* Example: create a new EGL project for
+
* "Web 2.0 application with services". Add the
+
* the Service type shown next to the server package,
+
* and add the Handler type to the client package.
+
*
+
* Test the example in the Rich UI Preview tab
+
* by typing valid input into the first text box; for example:
+
* 5, 12, 4
+
*/
+
  
// the file with a Service type
+
      myBinding IHttp? = Resources.getResource("binding:myBinding");
package server;
+
      call MyServiceType.calculate(myList)
 +
        using myBinding
 +
        returning to theCallBack
 +
        onException theExceptionHandler;
  
Service MyServiceType
+
      /*******************************************************************/
+
// variables and constants can be here
+
+
function calculate(myScores Int[] in) returns (Decimal(4,2))
+
numberOfScores, i, mySum Int;
+
numberOfScores = myScores.getSize();
+
  
for (i from 1 to numberOfScores by 1)
+
  end
mySum = myScores[i] + mySum;
+
end
+
+
return(mySum/numberOfScores);
+
end  
+
 
end
 
end
 +
</source> <!--
 +
You can demonstrate the access of a Service type under development only after you update two aspects of your deployment descriptor: Service Deployment and Resource Bindings. -->
  
// the file with a Handler type
+
Incidentally, you can retrieve the details from the HTTP response by adding a parameter of type IHTTP to the callback function: <source lang="java">
 +
  function theCallBack(retResult decimal(4, 2) in, myHttp IHTTP in)
 +
      myResult.text = retResult;
 +
 
 +
      /* display the response in JSON format */
 +
      SysLib.writeStdOut(myHttp.getResponse().body);
 +
end
 +
</source>
 +
 
 +
== Accessing a third-party REST service  ==
 +
 
 +
A Rich UI handler can invoke a proxy function, which must be in a package that is generated to JavaScript. The proxy function requires no logic at all: you access the service by setting values in function annotations, and you supplement those values with a deployment-descriptor entry.
 +
 
 +
The example in this section shows how to invoke a third-party REST service; specifically, the Airport Status service provided by the U.S. Federal Aviation Administration: [http://services.faa.gov/docs/tutorial/ Airport Status (http://services.faa.gov/docs/tutorial/)].
 +
 
 +
<source lang="java">
 +
/****************************************************************
 +
* Declare the binding variable                                *
 +
****************************************************************/
 +
  myBinding IHttp? = Resources.getResource("binding:USFAA");
 +
 
 +
 +
/****************************************************************
 +
* Call the proxy function                                      *
 +
****************************************************************/
 +
  call getAirportStatus(airportCode.text)
 +
      using myBinding returning to theCallBack
 +
      onException theExceptionHandler;
 +
 
 +
 +
/****************************************************************
 +
* Example:                                                    *
 +
*                                                              *
 +
* 1. Create a new EGL project for                              *
 +
*    "Web 2.0 client application with services".              *
 +
*                                                              *
 +
* 2. Create Record types with a few keystrokes:                *
 +
*                                                              *
 +
*    a. In your new project, right-click the                  *
 +
*      package named "common".                                  *
 +
*                                                              *
 +
*    b. Click New > Record.                                    *
 +
*                                                              *
 +
*    c. At the EGL Record wizard, name the file                *
 +
*      StatusRecordTypes and double-click Records from XML.  *
 +
*                                                              *
 +
*    d. At the Records from XML page, click Create from a URL. *
 +
*                                                              *
 +
*    e. Paste the following URL into the text area and click  *
 +
*      Finish:                                                *
 +
*                                                              *       
 +
        http://services.faa.gov/airport/status/IAD?format=xml  * 
 +
*                                                              *
 +
* 3. Copy and paste the code shown later. Specifically,        *
 +
*    add the Handler type and proxy-function library          *
 +
*    to the package named "client".                            *
 +
*                                                              * 
 +
* 4. In the deployment descriptor, create a resource-binding  *
 +
*    entry named USFAA and specify the base URI as follows:    *
 +
*                                                              *
 +
*      http://services.faa.gov/airport/status                *
 +
*                                                              *
 +
*    Avoid adding any spaces at the end of that input.        * 
 +
*                                                              *
 +
* 5. Test the example in the Rich UI Preview tab:              *
 +
*                                                              *   
 +
*    a. Type an airport code into the first text box;          *
 +
*      for example, LAX.  Other examples are JFK, DFW, RDU.  *
 +
*                                                              *
 +
*    b. Click Retrieve.                                        *
 +
*                                                              *
 +
* 6. As described in the example code, change the code so      *
 +
*    that you specify a detail in an HTTP header. Notice      *
 +
*    how easily you can set an HTTP header for advanced uses.  *
 +
*                                                              *
 +
* 7. Retest the example.                                      *
 +
*                                                              *
 +
****************************************************************/
 +
 +
/****************************************************************
 +
* The file with a Handler type named MyHandlerUSFAA            *
 +
****************************************************************/
 
package client;
 
package client;
  
import server.MyServiceType;
+
import common.AirportStatus;
 
import org.eclipse.edt.rui.widgets.GridLayout;
 
import org.eclipse.edt.rui.widgets.GridLayout;
import org.eclipse.edt.rui.widgets.TextField;
 
 
import org.eclipse.edt.rui.widgets.GridLayoutData;
 
import org.eclipse.edt.rui.widgets.GridLayoutData;
 +
import org.eclipse.edt.rui.widgets.TextLabel;
 +
import org.eclipse.edt.rui.widgets.TextField;
 
import dojo.widgets.DojoButton;
 
import dojo.widgets.DojoButton;
import dojo.widgets.DojoTextField;
+
import dojo.widgets.DojoTextArea;
  
handler MyHandler type RUIhandler{initialUI =[ui],  
+
handler MyHandlerUSFAA type RUIhandler{
onConstructionFunction = start,  
+
  initialUI =[ui], onConstructionFunction = start,  
cssFile = "css/ProjectInEDT.7.css",  
+
  cssFile = "css/MyClientAppWithService.css",  
title = "MyHandler"}
+
  title = "MyHandler"}
  
ui GridLayout{columns = 3, rows = 4, cellPadding = 4,  
+
  ui GridLayout{columns = 3, rows = 4, cellPadding = 4,  
children =[myResult, myButton, scores]};
+
                children =[myResult, myButton, airportCode, codeLabel]};
scores TextField{layoutData =  
+
  codeLabel TextLabel{
new GridLayoutData{row = 2, column = 2}};
+
      layoutdata =
myButton DojoButton{layoutData =  
+
        new GridLayoutData{
new GridLayoutData{row = 4, column = 2},  
+
            row = 2, column = 1, horizontalSpan = 2}, text = "Airport code: "};
text = "Calculate",  
+
  airportCode TextField{layoutData =  
onClick ::= ui_onClick};
+
        new GridLayoutData{row = 2, column = 3}};
myResult DojoTextField{layoutData =  
+
  myButton DojoButton{layoutData =  
new GridLayoutData{row = 4, column = 3}};
+
        new GridLayoutData{row = 4, column = 2},  
 +
                            text = "Retrieve", onClick ::= ui_onClick};
 +
  myResult DojoTextArea{layoutData = new GridLayoutData{row = 4, column = 3}};
 +
  myCommonError string = "Please specify a valid airport code; for example, LAX or DFW";
  
function start()
+
  use ProxyFunctions;
  
end
+
  function start()
 +
  end
  
function theExceptionHandler(exp AnyException in)
+
  function theExceptionHandler(exp AnyException in)
SysLib.writeStdOut(exp.messageID + " " + exp.message);
+
      if(exp.messageID == "CRRUI3655E")
+
        myResult.text = myCommonError;
if (exp isa ServiceInvocationException)
+
      else
SysLib.writeStdOut((exp as ServiceInvocationException).detail1);
+
        myResult.text = exp.messageID + " " + exp.message;
SysLib.writeStdOut((exp as ServiceInvocationException).detail2);
+
      end
SysLib.writeStdOut((exp as ServiceInvocationException).detail3);  
+
  end
end
+
end
+
  
function theCallBack(retResult decimal(4, 2) in)
+
  function theCallBack(statusResult AirportStatus in)
myResult.text = retResult;
+
end
+
  
function ui_onClick(event Event in)
+
      myResult.text = "At " + statusResult.name + ": " +
 +
                      statusResult.status.reason;
 +
  end
  
inputLength int = scores.text.length();
+
  function ui_onClick(event Event in)
  
myDelimiters string = ", ";
+
      if(airportCode.text.trim() != null)
myPosition int = 1;
+
myToken string;
+
myList int[];
+
while(myPosition < inputLength)
+
myToken = StringLib.getNextToken(scores.text,
+
myPosition, myDelimiters);
+
if(myToken != null)
+
myList.appendElement(myToken as int);
+
end
+
end
+
+
/************ Service access statements ***************************/
+
+
myService MyServiceType?{@DedicatedService};
+
call myService.calculate(myList) returning to theCallBack
+
onException theExceptionHandler;
+
  
/*******************************************************************/
+
        /************ Service access statements ***************************/
  
end
+
            myBinding IHttp? = Resources.getResource("binding:USFAA");
end
+
</source>
+
  
== Accessing an EGL REST-RPC service (version .7) ==
+
           
 +
            /*************************************************/ 
 +
           
 +
            // You can set an HTTP header, as shown next.
 +
            // myBinding.getRequest().headers = new dictionary;
 +
            // myBinding.getRequest().headers["accept"]="application/xml";
 +
           
 +
            /*************************************************/ 
 +
           
 +
            // The using clause is optional. The value overrides
 +
            // the value of the @Resource annotation, if any,
 +
            // in the proxy function.                               
 +
            call getAirportStatus(airportCode.text) using myBinding
 +
                returning to theCallBack onException theExceptionHandler;
  
Access of an EGL REST-RPC function is similar to accessing a dedicated service, but typically involves coding the variable declaration to reference an entry in the EGL deployment descriptor.  
+
        /*******************************************************************/
 +
      else
 +
        myResult.text = myCommonError;
 +
      end
 +
  end
 +
end
  
For example, you might change the previous handler to reference a deployment descriptor entry named <code>myService</code>. You can change the related variable declaration in one of two ways:
 
  
<source lang="java">
+
/****************************************************************
myService MyServiceType?{@Resource};
+
* The file with a Library type named ProxyFunctions            *
 +
****************************************************************/
 +
package client;
  
// or
+
import common.AirportStatus;
  
myService MyServiceType?{@Resource{bindingKey="myService"}};
+
library ProxyFunctions
</source>
+
 +
  function getAirportStatus(airportCode String) returns (AirportStatus) {
 +
    @Resource{uri = "binding:USFAA"},
 +
    @Rest{method = _GET,
 +
            uriTemplate = "/{airportCode}?format=application/xml",
  
You can demonstrate the access of a Service type under development only after you update two aspects of your deployment descriptor: Service Deployment and Resource Bindings. For details and a look at the version .8 code syntax, see [[EDT:Resource Binding Services|Service bindings]].
+
            /*************************************************/ 
 +
           
 +
            // if you placed format information in the HTTP "accept" header,
 +
            // you can use the following uriTemplate definition instead of the  
 +
            // one that places "?format=application/xml" into the URI:
  
To retrieve the details from the HTTP response, add a parameter of type IHTTP to the callback function: <source lang="java">
+
            // uriTemplate = "/{airportCode}",
function theCallBack(retResult decimal(4, 2) in, myHttp IHTTP in)
+
myResult.text = retResult;
+
  
// display the response in JSON format
+
            // if you do not use the second uriTemplate definition, the  
SysLib.writeStdOut(myHttp.getResponse().body);
+
            // "accept" detail is in both the header and the URI.
end
+
</source>
+
  
== Accessing a third-party REST service (version .7) ==
+
            // the REST service being accessed required the detail.   
 
+
           
<source lang="java">
+
            /*************************************************/ 
  
 +
    requestFormat = None, responseFormat = XML}
 +
  }
 +
  end
 +
end
 
</source>  
 
</source>  
  
<br><br><br>♦ [[EDT:Code snippets|Code snippets main page]] <br>
+
<br><br><br>♦ [[EDT:Code snippets|Code snippets main page]] <br>  
  
 
[[Category:EDT]]
 
[[Category:EDT]]

Latest revision as of 15:22, 10 September 2012

You can access services from a Rich UI application. This page gives code examples. For additional information, see Service bindings.

Accessing a dedicated service

The simplest way to deploy a service written in EGL is to include it with the Rich UI application. The service in that case is known as a dedicated service.

Assume that the service is named MyServiceType and the function of interest is named calculate. Here is a short example of the code necessary to access that service:

   call MyServiceType.calculate(myList) 
        returning to theCallBack
        onException theExceptionHandler;


Accessing an EGL service in either of its two forms

If the logic for a given service is written in EGL, the logic might be accessed as a dedicated service or as an EGL REST-RPC service. In that second case, the service is deployed outside of the Rich UI application, typically on a different server. 

Here is the simplest way to switch between accessing the identical EGL service logic in one way or another:

  1. In your code, declare a binding variable and embed it in a call statement.
  2. In the EGL deployment descriptor, define an entry.  To switch between the two forms of the same service logic, you can vary the entry in the same deployment descriptor or, more likely, can reference a different deployment descriptor with a same-named entry.

/********************************************************
 * Declare the binding variable                         * 
 ********************************************************/
   myBinding IHttp? = Resources.getResource("binding:myBinding");
 
/********************************************************
 * Call the service                                     * 
 ********************************************************/
   call MyServiceType.calculate(myList) 
      using myBinding
      returning to theCallBack 
      onException theExceptionHandler;
 
/********************************************************
 * Example: create a new EGL project for                *
 * "Web 2.0 client application with services". Add the  *
 * the Service type shown next to the server package,   * 
 * and add the Handler type to the client package.      *
 *                                                      *
 * Test the example in the Rich UI Preview tab          * 
 * as follows:                                          * 
 *                                                      *     
 *    1. Type valid input into the first text box;      * 
 *       for example: 5, 12, 4.                         *
 *                                                      * 
 *    2. Click '''Calculate'''.                         *
 ********************************************************/
 
/********************************************************
 * The file with a Service type                         *
 ********************************************************/
package server;
 
service MyServiceType
 
   // variables and constants can be here
   function calculate(myScores Int[] in) returns(Decimal(4, 2))
      numberOfScores, i, mySum Int;
      numberOfScores = myScores.getSize();
 
      for(i from 1 to numberOfScores)
         mySum = myScores[i] + mySum;
      end
 
      return(mySum/numberOfScores);
   end 
end
 
/********************************************************
 * The file with a Handler type                         *
 ********************************************************/
package client;
 
import server.MyServiceType;
import org.eclipse.edt.rui.widgets.GridLayout;
import org.eclipse.edt.rui.widgets.GridLayoutData;
import org.eclipse.edt.rui.widgets.TextField;
import org.eclipse.edt.rui.widgets.TextLabel;
 
import dojo.widgets.DojoButton;
import dojo.widgets.DojoTextField;
 
handler MyHandler type RUIhandler{
      initialUI =[ui], onConstructionFunction = start, 
      cssFile = "css/MyClientAppWithService.css", title = "MyHandler"}
 
   ui GridLayout{columns = 3, rows = 4, cellPadding = 4, 
                 children =[myResult, myButton, scores, codeLabel]};
 
   codeLabel TextLabel{layoutdata = new GridLayoutData{row = 2, column = 2}, 
                       text = "Numbers:"};                 
 
   scores TextField{layoutData = new GridLayoutData{row = 2, column = 3}};
 
   myButton DojoButton{layoutData = 
      new GridLayoutData{row = 4, column = 2}, 
                         text = "Calculate", onClick ::= ui_onClick};
 
   myResult DojoTextField{layoutData = new GridLayoutData{row = 4, column = 3}};
 
   function start()
 
   end
 
   function theExceptionHandler(exp AnyException in)
 
      SysLib.writeStdOut(exp.messageID + " " + exp.message);
 
      if(exp isa ServiceInvocationException)
         SysLib.writeStdOut((exp as ServiceInvocationException).detail1);
         SysLib.writeStdOut((exp as ServiceInvocationException).detail2);
         SysLib.writeStdOut((exp as ServiceInvocationException).detail3);
      end
   end
 
   function theCallBack(retResult decimal(4, 2) in)
      myResult.text = retResult;
   end
 
   function ui_onClick(event Event in)
 
      inputLength int = scores.text.length();
 
      myDelimiters string = ", ";
      myPosition int = 1;
      myToken string;
      myList int[];
 
      while(myPosition < inputLength)
         myToken = StringLib.getNextToken(scores.text, myPosition, myDelimiters);
 
            if(myToken != null)
               myList.appendElement(myToken as int);
            end
      end
 
      /************ Service access statements ***************************/
 
      myBinding IHttp? = Resources.getResource("binding:myBinding");
      call MyServiceType.calculate(myList) 
         using myBinding
         returning to theCallBack 
         onException theExceptionHandler;
 
      /*******************************************************************/
 
   end
end
Incidentally, you can retrieve the details from the HTTP response by adding a parameter of type IHTTP to the callback function:
   function theCallBack(retResult decimal(4, 2) in, myHttp IHTTP in)
      myResult.text = retResult;
 
      /* display the response in JSON format */
      SysLib.writeStdOut(myHttp.getResponse().body);
end

Accessing a third-party REST service

A Rich UI handler can invoke a proxy function, which must be in a package that is generated to JavaScript. The proxy function requires no logic at all: you access the service by setting values in function annotations, and you supplement those values with a deployment-descriptor entry.

The example in this section shows how to invoke a third-party REST service; specifically, the Airport Status service provided by the U.S. Federal Aviation Administration: Airport Status (http://services.faa.gov/docs/tutorial/).

/****************************************************************
 * Declare the binding variable                                 * 
 ****************************************************************/
   myBinding IHttp? = Resources.getResource("binding:USFAA");
 
 
/****************************************************************
 * Call the proxy function                                      * 
 ****************************************************************/
   call getAirportStatus(airportCode.text)
      using myBinding returning to theCallBack
      onException theExceptionHandler;
 
 
/****************************************************************
 * Example:                                                     *
 *                                                              *
 * 1. Create a new EGL project for                              *
 *    "Web 2.0 client application with services".               *
 *                                                              * 
 * 2. Create Record types with a few keystrokes:                *
 *                                                              * 
 *    a. In your new project, right-click the                   *
 *       package named "common".                                  * 
 *                                                              * 
 *    b. Click New > Record.                                    *
 *                                                              * 
 *    c. At the EGL Record wizard, name the file                * 
 *       StatusRecordTypes and double-click Records from XML.   *
 *                                                              * 
 *    d. At the Records from XML page, click Create from a URL. *
 *                                                              *
 *    e. Paste the following URL into the text area and click   *
 *       Finish:                                                *
 *                                                              *         
         http://services.faa.gov/airport/status/IAD?format=xml  *  
 *                                                              *
 * 3. Copy and paste the code shown later. Specifically,        * 
 *    add the Handler type and proxy-function library           * 
 *    to the package named "client".                            * 
 *                                                              *  
 * 4. In the deployment descriptor, create a resource-binding   * 
 *    entry named USFAA and specify the base URI as follows:    *
 *                                                              * 
 *       http://services.faa.gov/airport/status                 *
 *                                                              * 
 *    Avoid adding any spaces at the end of that input.         *  
 *                                                              *
 * 5. Test the example in the Rich UI Preview tab:              * 
 *                                                              *     
 *    a. Type an airport code into the first text box;          * 
 *       for example, LAX.  Other examples are JFK, DFW, RDU.   *
 *                                                              * 
 *    b. Click Retrieve.                                        *
 *                                                              * 
 * 6. As described in the example code, change the code so      *
 *    that you specify a detail in an HTTP header. Notice       *
 *    how easily you can set an HTTP header for advanced uses.  *
 *                                                              * 
 * 7. Retest the example.                                       *
 *                                                              *
 ****************************************************************/
 
/****************************************************************
 * The file with a Handler type named MyHandlerUSFAA            *
 ****************************************************************/
package client;
 
import common.AirportStatus;
import org.eclipse.edt.rui.widgets.GridLayout;
import org.eclipse.edt.rui.widgets.GridLayoutData;
import org.eclipse.edt.rui.widgets.TextLabel;
import org.eclipse.edt.rui.widgets.TextField;
import dojo.widgets.DojoButton;
import dojo.widgets.DojoTextArea;
 
handler MyHandlerUSFAA type RUIhandler{
   initialUI =[ui], onConstructionFunction = start, 
   cssFile = "css/MyClientAppWithService.css", 
   title = "MyHandler"}
 
   ui GridLayout{columns = 3, rows = 4, cellPadding = 4, 
                 children =[myResult, myButton, airportCode, codeLabel]};
   codeLabel TextLabel{
      layoutdata = 
         new GridLayoutData{
            row = 2, column = 1, horizontalSpan = 2}, text = "Airport code: "};
   airportCode TextField{layoutData = 
         new GridLayoutData{row = 2, column = 3}};
   myButton DojoButton{layoutData = 
         new GridLayoutData{row = 4, column = 2}, 
                            text = "Retrieve", onClick ::= ui_onClick};
   myResult DojoTextArea{layoutData = new GridLayoutData{row = 4, column = 3}};
   myCommonError string = "Please specify a valid airport code; for example, LAX or DFW";
 
   use ProxyFunctions;
 
   function start()
   end
 
   function theExceptionHandler(exp AnyException in)
      if(exp.messageID == "CRRUI3655E")
         myResult.text = myCommonError;
      else
         myResult.text = exp.messageID + " " + exp.message;
      end
   end
 
   function theCallBack(statusResult AirportStatus in)
 
      myResult.text = "At " + statusResult.name + ": " +
                      statusResult.status.reason;
   end
 
   function ui_onClick(event Event in)
 
      if(airportCode.text.trim() != null)
 
         /************ Service access statements ***************************/
 
            myBinding IHttp? = Resources.getResource("binding:USFAA");
 
 
            /*************************************************/  
 
            // You can set an HTTP header, as shown next. 
            // myBinding.getRequest().headers = new dictionary;
            // myBinding.getRequest().headers["accept"]="application/xml";	
 
            /*************************************************/  
 
            // The using clause is optional. The value overrides 
            // the value of the @Resource annotation, if any, 
            // in the proxy function.                                 
            call getAirportStatus(airportCode.text) using myBinding
                 returning to theCallBack onException theExceptionHandler;
 
         /*******************************************************************/
      else
         myResult.text = myCommonError;
      end
   end
end
 
 
/****************************************************************
 * The file with a Library type named ProxyFunctions            *
 ****************************************************************/
package client;
 
import common.AirportStatus;
 
library ProxyFunctions
 
   function getAirportStatus(airportCode String) returns (AirportStatus) {
 	    @Resource{uri = "binding:USFAA"},
	    @Rest{method = _GET, 
            uriTemplate = "/{airportCode}?format=application/xml",
 
            /*************************************************/  
 
            // if you placed format information in the HTTP "accept" header, 
            // you can use the following uriTemplate definition instead of the 
            // one that places "?format=application/xml" into the URI:  
 
            // uriTemplate = "/{airportCode}",
 
            // if you do not use the second uriTemplate definition, the 
            // "accept" detail is in both the header and the URI. 
 
            // the REST service being accessed required the detail.  
 
            /*************************************************/  
 
	    requestFormat = None, responseFormat = XML}
   }
   end	
end




Code snippets main page

Back to the top