Skip to main content

Creating a Web Client in a Production

This topic describes how to create an InterSystems IRIS® Interoperability web client. At a high level, your InterSystems IRIS Interoperability web client receives InterSystems IRIS Interoperability requests from elsewhere within the production, converts them to SOAP requests, and sends them to the appropriate web service. Similarly, it receives SOAP responses, converts them into InterSystems IRIS responses, and sends them back within the production.

Tip:

InterSystems IRIS also provides specialized business service classes that use SOAP, and one of those might be suitable for your needs. If so, no programming would be needed. See Connectivity Options.

Overview

An InterSystems IRIS Interoperability web client consists of the following parts:

  • A proxy client class that defines a proxy method for each method defined by the web service. Each proxy method uses the same signature used by the corresponding web service method and invokes that method when requested.

  • A business operation that uses the InterSystems IRIS Interoperability SOAP outbound adapter to invoke the proxy client.

  • Supporting classes as needed to define XML types and production messages.

The following figure shows how the business operation, adapter, and proxy client class work together. Supporting classes are not shown here.

operation uses MessageMap to send requests to outbound adapter using InvokeMethod which sends it to proxy client which sends

In the preceding figure, all items within dashed lines can be generated programmatically. You can then edit this code as needed.

For a more detailed look at these parts, see InterSystems IRIS Support for Web Clients.

Basic Steps

This section outlines the basic steps to create an InterSystems IRIS Interoperability web client.

To create an InterSystems IRIS Interoperability web client:

  1. Programmatically generate business operation class, proxy client class, and supporting classes, as described below.

  2. Check whether you need to adjust the types of the inputs and outputs of the methods, as described below.

Generating the Client Classes

To generate a set of web client classes for a given WSDL:

  1. Create an instance of %SOAP.WSDL.ReaderOpens in a new tab.

  2. Optionally set properties to control the behavior of your instance.

    Property Purpose
    CompileFlags Specifies the flags to use when compiling the generated classes. The initial expression is "dk"; use $System.OBJ.ShowFlags() to get information on the available flags.
    MakePersistent If this property is 1, the proxy client is a persistent object; otherwise, it is a registered object. The initial expression is 0.
    MakeSerial If this property is 1 and if MakePersistent is 1, the proxy client is a serial class. The initial expression is 0.
    OutputTypeAttribute Controls how the WSDL reader sets the OUTPUTTYPEATTRIBUTE parameter in the proxy client that it generates; which controls the use of the xsi:type attribute in the SOAP messages. See Creating Web Services and Web Clients.
    MakeBusinessOperation Specifies whether to generate a business operation and related request and response objects. The ADAPTER setting for this business operation is EnsLib.SOAP.OutboundAdapterOpens in a new tab. This option works only if you are working within an interoperability-enabled namespace.

    For other properties, see the class documentation for %SOAP.WSDL.ReaderOpens in a new tab.

  3. Invoke the Process() method, providing the following arguments:

    • The first argument must be the URL of the WSDL of the web service or the name of the WSDL file (including its complete path). Depending on the configuration of the web service, it may be necessary to append a string that provides a suitable username and password; see the examples.

    • The optional second argument is the name of the package in which the reader should place the generated classes. If you do not specify a package, InterSystems IRIS uses the service name as the package name.

Generated Classes and XMLKEEPCLASS

When you generate web client classes, you specify the package for the classes. If this package is the same as an existing package, by default the tool will overwrite any existing classes that have the same name. To prevent InterSystems IRIS from overwriting a class definition, add the XMLKEEPCLASS parameter to that class and set this parameter equal to 1.

Generated Classes for an InterSystems IRIS Interoperability Web Client

This section provides information about the generated web client classes.

Consider a web service named MyService that has the following details:

  • It is hosted at https://devsys/csp/mysamples/MyApp.AddService.CLS

  • The target XML namespace for the web service is http://www.myapp.org

  • It defines a web method named AddService, which accepts two complex numbers as arguments and returns the result.

Suppose that you generate a web client client for this web service. If you specify the package for the client classes as MyClient, InterSystems IRIS generates the following classes:

  • It generates the MyClient.BusOp.MyServiceSoap class, which defines the business operation.

    Class MyClient.BusOp.MyServiceSoap Extends Ens.BusinessOperation
    {
    
    Parameter ADAPTER = "EnsLib.SOAP.OutboundAdapter";
    
    Method Add(pRequest As MyClient.BusOp.AddRequest,
    Output pResponse As MyClient.BusOp.AddResponse) As %Library.Status
    {
       Set ..Adapter.WebServiceClientClass = "MyClient.MyServiceSoap"
       Set tSC = ..Adapter.InvokeMethod("Add",.AddResult,
    pRequest.a,pRequest.b) Quit:$$$ISERR(tSC) tSC
    
       Set tSC = pRequest.NewResponse(.pResponse) Quit:$$$ISERR(tSC) tSC
       Set pResponse.AddResult=AddResult
       Quit $$$OK
    }
    
    XData MessageMap
    {
    <MapItems>
        <MapItem MessageType="MyClient.BusOp.AddRequest">
            <Method>Add</Method>
        </MapItem>
    </MapItems>
    }
    
    }
    
  • It generates the MyClient.AddServiceSOAP class, the proxy client class:

    Class MyClient.AddServiceSoap Extends %SOAP.WebClient
    {
    
    /// This is the URL used to access the web service.
    Parameter LOCATION = "https://devsys/csp/mysamples/MyApp.AddService.cls";
    
    /// This is the namespace used by the Service
    Parameter NAMESPACE = "http://www.myapp.org";
    
    /// Use xsi:type attribute for literal types.
    Parameter OUTPUTTYPEATTRIBUTE = 1;
    
    /// This is the name of the Service
    Parameter SERVICENAME = "AddService";
    
    Method Add(a As MyClient.ComplexNumber, b As MyClient.ComplexNumber)
       As MyClient.ComplexNumber [ Final, 
       SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
    {
     Quit ..WebMethod("Add").Invoke($this,
          "http://www.myapp.org/MyApp.AddService.Add",.a,.b)
    }
    
    }
  • It generates the request and response message classes needed by the business operation. The request class is as follows:

    Class MyClient.BusOp.AddRequest Extends Ens.Request
    {
    
    Parameter RESPONSECLASSNAME = "MyClient.BusOp.AddResponse";
    
    Property a As MyClient.ComplexNumber;
    
    Property b As MyClient.ComplexNumber;
    
    }

    The response class is as follows:

    Class MyClient.BusOp.AddResponse Extends Ens.Response
    {
    
    Property AddResult As MyClient.ComplexNumber;
    
    }
    
  • Finally, it generates the MyClient.ComplexNumber class, which defines a complex number and which is used by the other classes.

    /// Created from: http://devsys/csp/mysamples/MyApp.AddService.CLS?WSDL=1
    Class MyClient.ComplexNumber Extends (%RegisteredObject, %XML.Adaptor)
    {
    Parameter XMLNAME = "ComplexNumber";
    
    Parameter XMLSEQUENCE = 1;
    
    Property Real As %xsd.double(XMLNAME = "Real") [ SqlFieldName = _Real ];
    
    Property Imaginary As %xsd.double(XMLNAME = "Imaginary");
    
    }

When you compile these classes, the compiler also generates a class for each method defined in the web service. These classes are not automatically added to your project and their internal details are subject to change. These classes extend %SOAP.ProxyDescriptorOpens in a new tab, which you should never subclass yourself.

Creating a Business Operation Class Manually

Rather than using the generated business operation class, you can create your own class. This section describes how to do so. It discusses the following:

Basic Requirements of the Class

The following list describes the basic requirements of the business operation class:

  • Your business operation class should extend Ens.BusinessOperationOpens in a new tab.

  • In your class, the ADAPTER parameter should equal EnsLib.SOAP.OutboundAdapterOpens in a new tab.

  • In your class, the INVOCATION parameter should specify the invocation style you want to use, which must be one of the following.

    • Queue means the message is created within one background job and placed on a queue, at which time the original job is released. Later, when the message is processed, a different background job will be allocated for the task. This is the most common setting.

    • InProc means the message will be formulated, sent, and delivered in the same job in which it was created. The job will not be released to the sender’s pool until the message is delivered to the target. This is only suitable for special cases.

  • Your class should define one method for each method of the proxy client, as described in the following section.

  • Your class should define a message map that includes one entry for each method. A message map is an XData block entry that has the following structure:

    XData MessageMap
    {
    <MapItems>
      <MapItem MessageType="messageclass">
        <Method>methodname</Method>
      </MapItem>
      ...
    </MapItems>
    }
    
    

You will also need to define the production message classes that the business operation uses.

Basic Requirements of the Methods

Within your business operation class, your methods should invoke the proxy methods. Here the general requirements are as follows:

  1. The method should have the same signature as the proxy method that it is invoking.

  2. The method should be marked with the WebMethod keyword.

  3. The method should set the SoapBindingStyle and SoapBodyUse keywords as expected by the proxy client. (That is, use the same values as in the signature of the corresponding proxy method.)

  4. The method should set the WebServiceClientClass property of the adapter. When this property is set, a proxy client instance is created and placed in the %Client property of the adapter.

  5. The method should call the corresponding proxy method, using one of the techniques in the next section.

  6. The method should check the status.

  7. Then:

    • In the case of success, create a new response message (via the NewResponse() method of the request) and set its properties as appropriate.

    • In the case of failure, quit with the error.

Ways to Execute the Proxy Methods

Within your business operation, your methods should execute the proxy methods of the proxy client class. You can do this in multiple ways, which are best shown via an example. This section uses an example web service that has a web method named GetStock that accepts a stock symbol (a string) and returns a number. Suppose that you have used generated a proxy client (GetStock.StockServiceSoap), which contains a method called GetStock.

Also suppose that you have created message classes as follows:

Class GetStock.BusOp.GetQuoteRequest Extends Ens.Request
{

Parameter RESPONSECLASSNAME = "GetStock.BusOp.GetQuoteResponse";

Property StockName As %String;

}

And

Class GetStock.BusOp.GetQuoteResponse Extends Ens.Response 
{

Property StockValue As %Numeric;

}

To execute the proxy method GetStock, your business operation class can do any of the following:

  • Call the InvokeMethod() method of the adapter and specify the name of the proxy method to run, as well as any number of arguments. In this case, there is only one argument (which we specify as pRequest.StockName). For example:

    Method GetQuote1(pRequest As GetStock.BusOp.GetQuoteRequest,
    Output pResponse As GetStock.BusOp.GetQuoteResponse) As %Status
    {
     set ..Adapter.WebServiceClientClass = "GetStock.StockServiceSoap"
    
     set status = ..Adapter.InvokeMethod("GetQuote",.answer,pRequest.StockName)
     if $$$ISERR(status) quit status
    
     set pResponse=##class(GetStock.BusOp.GetQuoteResponse).%New()
     set pResponse.GetQuoteResult=answer
     quit $$$OK
    }
    
  • Access the %Client property of the adapter, which gives you an instance of the proxy client class, and execute the proxy method of that property. The %Client property is set when you set the WebServiceClientClass property. In this case, %Client has a method named GetQuote, which accepts a string stock symbol. For example:

    Method GetQuote2(pRequest As GetStock.BusOp.GetQuoteRequest,
    Output pResponse As GetStock.BusOp.GetQuoteResponse) As %Status
    {
     set ..Adapter.WebServiceClientClass = "GetStock.StockServiceSoap"
    
     set client=..Adapter.%Client
     set answer=client.GetQuote("GRPQ")
    
     set pResponse=##class(GetStock.BusOp.GetQuoteResponse).%New()
     set pResponse.GetQuoteResult=answer
     quit $$$OK
    }

    Note that with this technique, you do not have access to the retry logic of InterSystems IRIS.

  • Create a proxy method object by calling the WebMethod() method of the adapter. Set properties of this object as appropriate (one property per named argument). In this case, WebMethod() returns an object with one property: StockName. After setting properties as needed, call the Invoke() method of that object. For example:

    Method GetQuote3(pRequest As GetStock.BusOp.GetQuoteRequest,
    Output pResponse As GetStock.BusOp.GetQuoteResponse) As %Status
    {
     set ..Adapter.WebServiceClientClass = "GetStock.StockServiceSoap"
    
    
     set proxymethod=..Adapter.WebMethod("GetQuote")
     set proxymethod.StockName=pRequest.StockName
    
    
     set status=..Adapter.Invoke(proxymethod)
     if $$$ISERR(status) quit status
    
    
     set pResponse=##class(GetStock.BusOp.GetQuoteResponse).%New()
     set pResponse.GetQuoteResult=proxymethod.%Result
     quit $$$OK
    }
    

    In this case, you can provide any number of arguments.

Reference Information

This section provides reference information for the adapter property and methods mentioned in the previous section.

%Client property
%SOAP.WebClient 

The associated instance of the proxy client (an instance of %SOAP.WebClientOpens in a new tab). This property is set when you set the WebServiceClientClass property of the adapter.

InvokeMethod() method
Method InvokeMethod(pMethodName As %String,
       Output pResult As %RegisteredObject,
       pArgs...) As %Status

Calls the specified method of the proxy client class, passing all the arguments and returns the status. The output is returned by reference as the second argument.

WebMethod() method
Method WebMethod(pMethodName As %String) As %SOAP.ProxyDescriptor

Returns an object that corresponds to the specified method. This object has one property corresponding to each method argument; you should set this properties before using the Invoke() method. For details on %SOAP.ProxyDescriptorOpens in a new tab, see the class reference.

Invoke() method
Method Invoke(pWebMethod As %SOAP.ProxyDescriptor) As %Status

Calls the given method and returns the status.

Adding and Configuring the Web Client

To add your InterSystems IRIS Interoperability web client to a production, use the Management Portal to do the following:

  1. Add an instance of your custom business operation class to the production, specifically the generated business operation class.

  2. Enable the business operation.

  3. Specify appropriate values for the runtime settings of the associated adapter, as discussed below.

  4. Run the production.

The following subsections describes the runtime settings for your IRIS Interoperability web client, which fall into several general groups:

For settings not listed here, see Settings in All Productions.

Specifying Basics

The following settings specify the basic information for the InterSystems IRIS Interoperability web client:

Specifying Credentials

The web service that you are accessing might require a username and password. In general, the InterSystems IRIS Interoperability SOAP client can log in to a web service in either of the following ways:

  • You can use WS-Security user authentication. In this case, you include a WS-Security header in the SOAP request; this header includes the username and password. The proxy client automatically does this if you specify a value for the SOAP Credentials setting.

    Caution:

    Ensure that you are using TLS between the web client and the web service. The WS-Security header is sent in clear text, so this technique is not secure unless TLS is used.

  • You can use basic HTTP user authentication, which is less secure than WS-Security but is sometimes required. In this case, you include the username and password in the HTTP header of the SOAP request. The proxy client automatically does this if you specify a value for the Credentials setting.

Use the technique that is appropriate for the web service you are using.

Specifying a TLS Configuration

If your web server supports it, you can connect with TLS. To do so, specify a value for the SSL Configuration setting.

Note:

You must also ensure the web service is at a URL that uses https://. The web service location is determined by the Web Service URL setting; if this is not specified, the InterSystems IRIS Interoperability web client assumes the web service is at the URL specified by the LOCATION parameter in the proxy client class.

Specifying a Proxy Server

You can communicate with the web service via a proxy server. To set this up, use Proxy Server and other settings in the Proxy Settings group.

FeedbackOpens in a new tab