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:Resource Binding Services"

Line 24: Line 24:
 
   onException myExceptionHandler;
 
   onException myExceptionHandler;
 
</pre>  
 
</pre>  
*If you are accessing a REST or EGL REST-RPC service, you can encapsulate the "how" and "where" information in a single location, by adding a '''proxy function''' to a library or handler. In this case, the call statement invokes the proxy function, which acts as an intermediary between the '''call''' statement and the back-end code. <br><br>(The proxy function was already in use for IBM i program access and is now in use for service access as well. The change occurred after EDT version .081 Milestone 2. For details on the prior support for service access, see the EDT help topics in the build for 0.81 Milestone 2.)&nbsp; <br><br>At development time, the proxy function is empty. It lists the invocation parameters and, if appropriate, a return type. Here is the outline of such a function:
+
*If you are accessing a REST or EGL REST-RPC service, you can encapsulate the "how" and "where" information in a single location, by adding a''proxy function'' to a library or handler. In this case, the '''call''' statement invokes the proxy function, which acts as an intermediary between th<span style="font-weight: bold;">at</span statement and the back-end code. <br><br>(The proxy function was already in use for IBM i program access and is now in use for service access as well. The change for service access occurred after EDT version .081 Milestone 2. For details on the prior support for service access, see the EDT help topics in the build for 0.81 Milestone 2.)&nbsp; <br><br>At development time, the proxy function is empty. It lists the invocation parameters and, if appropriate, a return type. Here is the outline of such a function:
  
 
<br>  
 
<br>  
Line 50: Line 50:
 
end
 
end
 
</pre>  
 
</pre>  
For further details on support for IBM i, see
+
<br>
 +
 
 +
To add "where" information to the proxy function, specify the '''Resource''' annotation at the same level as the other annotation.&nbsp; Here is an example:
 +
 
 +
<pre>
 +
function myExternalLogic(p1 string, p2 string)RETURNS(int) {
 +
  @Resource{uri = "binding:myDD#myEntry"},
 +
  @Rest {
 +
      method = HttpMethod._GET,
 +
      uriTemplate = "http://www.example.com:9080/org/search/?string01={p1}&string02={p2}"
 +
  }
 +
}
 +
end
 +
</pre>
 +
 
  
<br>
 
  
 
<br> <br> <!-- If the purpose of a resource binding is service access, the definition is called a ''service binding''. -->  
 
<br> <br> <!-- If the purpose of a resource binding is service access, the definition is called a ''service binding''. -->  

Revision as of 14:20, 18 June 2012

Resource Binding Introduction


To access a service, you must specify where the external logic resides, and how to interact with that logic. You can think of the two kinds of information in an abbreviated way: "where" and "how."

To specify "where," you typically retrieve access details from an entry in the EGL deployment descriptor. To specify "how," you might act in one of two ways, depending on the kind of logic being accessed:

  • If you are accessing an EGL REST-RPC service, you can specify "how" in the call statement. In this case, the call statement references the Service operation. The usage is particularly simple. The usage is available whether the service is being deployed on a remote platform or as a dedicated service. 

    Here is an example of accessing a remote EGL REST-RPC service:
myBindingVar HttpRest{@Resource(uri="http://www.example.com:9080/MyProject/restServices/MyServiceType"};

call 
   MyServiceType.myFunction("abc")          // "how"
   using myBindingVar                       // "where"
   returning to myCallBackFunction
   onException myExceptionHandler;
 
Here is an example of accessing a dedicated EGL service:
myBindingVar HttpProxy{};

call 
   MyServiceType.myFunction("abc")          // "how"
   using myBindingVar                       // "where"
   returning to myCallBackFunction
   onException myExceptionHandler;
  • If you are accessing a REST or EGL REST-RPC service, you can encapsulate the "how" and "where" information in a single location, by adding aproxy function to a library or handler. In this case, the call statement invokes the proxy function, which acts as an intermediary between that</span statement and the back-end code.

    (The proxy function was already in use for IBM i program access and is now in use for service access as well. The change for service access occurred after EDT version .081 Milestone 2. For details on the prior support for service access, see the EDT help topics in the build for 0.81 Milestone 2.) 

    At development time, the proxy function is empty. It lists the invocation parameters and, if appropriate, a return type. Here is the outline of such a function:


function myExternalLogic(p1 string, p2 string)RETURNS(int)
   {}
end

You do not write any logic for the proxy function. Instead, you tell an EGL generator what is required. In particular, you specify an annotation that is specific to the kind of back-end code that will be invoked. 

Here are examples:

  • For a REST service invocation, declare a Rest annotation:

function myExternalLogic(p1 string, p2 string)RETURNS(int) {
   @Rest {
      method = HttpMethod._GET, 
      uriTemplate = "http://www.example.com:9080/org/search/?string01={p1}&string02={p2}" 
   }
}
end


  • For an EGL REST-RPC service invocation, declare an EglRestRPC annotation:

function myExternalLogic(p1 string, p2 string)RETURNS(int) {
   @EGLRestRpc{serviceName="MyServiceType.myFunction"};
}
end


To add "where" information to the proxy function, specify the Resource annotation at the same level as the other annotation.  Here is an example:

 
function myExternalLogic(p1 string, p2 string)RETURNS(int) {
   @Resource{uri = "binding:myDD#myEntry"},
   @Rest {
      method = HttpMethod._GET, 
      uriTemplate = "http://www.example.com:9080/org/search/?string01={p1}&string02={p2}" 
   }
}
end










[ the rest of this description is being rewritten.... but the next paragraphs focus on the nature of the resource binding.... ]

The main detail is in one of three categories:

  • If the service is deployed on an application server, you can specify a Universal Resource Identifier (URI) that begins with the http: or https: prefix. Here is an example:
http://myserver:8080/myproject/restservices/myService
Although you can run the deployed service during an EGL debugging session, the EGL debugger does not step into the service.
  • If the service is available in your workspace and was written in EGL, you can use a workspace URI, which is an identifier that points to a workspace location. Here is an example:
workspace://mySourceProject/servicepackage.myService
In this case, the URI is useful only at development time, and an internal Test Server enables you to debug the code. In this case, your task in the EGL Deployment Descriptor editor is twofold: to update the Service Deployment tab as well as the Resource Bindings tab. You must arrange for service deployment.
  • If a Rich UI application includes a Service type that will be deployed as a dedicated service, an Internal Test Server enables you to debug the code.

    In this case, the EGL deployment descriptor is never used. You declare a binding variable of type HttpProxy and issue a call statement, as shown here:
myBindingVar HttpProxy;
call MyServiceType.myFunction()
   using myBindingVar
   returning to myCallBackFunction
   onException myExceptionHandler;

Here is alternative code that has the same effect, but declares a binding-variable value in the call statement itself:

call MyServiceType.myFunction() 
   using new HttpProxy
   returning to myCallBackFunction
   onException myExceptionHandler;


Defining a service binding in the EGL deployment descriptor

At this writing, you can bind to a REST or EGL REST-RPC service. The distinctions among the service types are explained here: http://www.eclipse.org/edt/papers/topics/egl_soa_overview.html

To define a service binding in the EGL deployment descriptor, do as follows:

  • In an EGL project, expand the EGLSource folder and double-click the deployment descriptor, which has the file extension .egldd.  
  • Click the Resource Bindings tab. The Resource Bindings Configuraton page is displayed.
  • Click Add and, at the Add a Resource Binding page, select REST Service Binding. The Add a REST Service Binding page is displayed, as shown here:

Bind Img8.JPG


  • In the topmost field, specify the binding name. You can reference that name in your code, whether in a Resource annotation or in a statement that invokes the Resources.getResource function.
  • In the Base URI field, specify a URI, which might be a workspace URI:
    • If you are accessing an EGL REST-RPC service, specify the complete URI.
    • If you are accessing a third-party REST service, you might decide to include only high-level details and to supplement them with values that are stored in an Interface type. For specifics, see the following help topic: "Creating an Interface part to access a REST service."
  • The sessionCookieID field is not in use.

If you are defining a service binding for a Service type in your workspace, you must ensure that the service will be deployed: 

  • Switch to the Service Deployment tab. If the service is not already listed, click Add. The Add Web Services page is displayed.

Bind Img6.JPG 

  • Highlight the Service type of interest, click Add, and click Finish. The Web Service Deployment tab is re-displayed with the new detail.

Bind Img7.JPG

  • To save the deployment descriptor, press Ctrl-S.

Retrieving one or another service binding in your code

In an innovation that began after version 0.81 Mileston 2 (M2), your task is to declare a binding variable...




In version 0.81 M2 and earlier, your task was to declare a service-access variable, as shown here:

myService MyInterfaceType?; 

    /* that declaration could have included 
       a Resource annotation, as shown here:

        myService MyInterfaceType?  
           { @Resource {uri="binding:MyGermanBinding"} };           // 0.81 M2 syntaz

if ( ... )

   myService = Resources.getResource("binding:MyEnglishBinding");   // 0.81 M2 syntax   

else

   myService = Resourc.getResource("binding:MyFrenchBinding");      // 0.81 M2 syntax

end

    /* here, you can access the service operations of 
       one or the other service, assuming that the two 
       have similar interfaces.                             */    

Retrieving a service binding and changing it in your code

Here is an example of preparing a variable and then using it to access a third-party REST service:

myService MyServiceType?;                                          
http HttpRest{@Resource{uri="binding:myService"}};                  /.8 syntax
http.request.encoding = encoding.json;                                  
call myService.myFunction() using http                              /.8 syntax 
   returning to myCallBackFunction 
   onException myExceptionHandler;


The code acts as follows:

  1. Declares an access variable. 

    The declaration references an Interface type that typically includes one or more uriTemplate annotation fields, each of which is a set of lower-level URI qualifiers that are resolved at run time. A resolved template might be this: /GetWeatherByZipCode?zipCode=27709 

  2. Accesses a new instance of an HTTPRest object.

    That object provides a higher-level URI such as http: //www.example.com/myproject/restservices/weather_service

    In this case, the object contains details that are retrieved from a service binding in the EGL deployment descriptor. If you do not specify a uri annotation field, the name of the service binding is assumed to be the name of the variable. In the example, the value of the annotation field defaults to "binding:myService".

    For details on the HttpRest object, see the help topic named "eglx.http package."

  3. Adds detail to the HTTPRest object; for example, to ensure that data is transferred to and from the service in JSON format.

  4. Invokes the Resources.completeBind function so that the variable references the HTTPRest object.

Creating a service binding in your code

You can create a service binding in your code, in which case the EGL deployment descriptor is not involved. For example, you might substitute the second statement in the following code for the object declaration that was shown in the preceding section:

myService IMyService?; 
http HttpRest = new HttpRest{
   restType = eglx.rest.ServiceType.TrueRest, 
   uri = "www.example.com/myproject/restservices/weather_service"};
myBinding.request.encoding = Encoding.json;
call myService.myFunction() using http                             // .8 syntax   
   returning to myCallBackFunction
   onException myExceptionHandler;

For details on the HttpRest object, see the help topic named "eglx.http package."


Next:  SQL database bindings

Previous:  Resource binding introduction

Back to the top