Skip to main content

Creating Web Clients

A web client is software that accesses a web service. A web client provides a set of proxy methods, each of which corresponds to a method of the web service. A proxy method uses the same signature as the web service method to which it corresponds, and it invokes the web service method when asked to do so. This topic describes how to create and use web clients in InterSystems IRIS® data platform.

For information on logging SOAP calls to your InterSystems IRIS web clients, see InterSystems IRIS SOAP Log.

Note:

For an InterSystems IRIS web service, the automatically generated WSDL might not include information about the SOAP header elements:

  • If you add SOAP headers manually by setting the HeadersOut property, be sure to follow the instructions in Specifying Supported Header Elements, in Adding and Using Custom Header Elements. If you do, the WSDL contains all the applicable information. Otherwise, it does not, and you must save the WSDL to a file and edit it manually as needed.

  • If you add WS-Security header elements by setting the SecurityOut property (as described in Securing Web Services), the WSDL does not include all needed information. (This is because the WSDL is generated at compile time and the headers are added later, at runtime.) In this case, save the WSDL to a file and edit it manually as needed.

    For many reasons, it is simpler and easier to add WS-Security elements by using WS-Policy, as described in Creating and Using Policies. With WS-Policy, the generated WSDL includes all needed information.

  • In other cases, the generated WSDL includes all needed information.

Note that the W3C specifications do not require a web service to provide a generated WSDL.

Generating the Client Classes Programmatically

You generate the client classes programmatically by using the %SOAP.WSDL.ReaderOpens in a new tab class. To generate the client classes programmatically:

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

  2. Optionally set properties to control the behavior of your instance. The subsections provide details.

    Note that if the WSDL is at a location that uses SSL, %SOAP.WSDL.ReaderOpens in a new tab will (by default) checks whether the certificate server name matches the DNS name used to connect to the server. If these names do not match, the connection is not permitted. This default behavior prevents man in the middle attacks and is described in RFC 2818Opens in a new tab, section 3.1; also see RFC 2595Opens in a new tab, section 2.4.

    To disable this check, set the SSLCheckServerIdentity property of the instance equal to 0.

  3. If you need the ability to control the HTTP request in a way that is not directly supported by %SOAP.WSDL.ReaderOpens in a new tab, do this:

    1. Create an instance of %Net.HttpRequestOpens in a new tab and set its properties as needed.

    2. For your instance of %SOAP.WSDL.ReaderOpens in a new tab, set the HttpRequest property equal to the instance of %Net.HttpRequestOpens in a new tab that you just created.

    For example, you might do this if the server requires authentication. See Providing Login Credentials in Sending HTTP Requests.

  4. Invoke the Process() method of your instance:

    method Process(pLocationURL As %String, pPackage As %String = "") as %Status 
    
    • pLocationURL 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.

    • pPackage is the name of the package in which to place the generated classes. If you do not specify a package, InterSystems IRIS uses the service name as the package name.

      Note:

      If this package is the same as an existing package, by default the tool overwrites any existing classes that have the same name. To prevent the tool from overwriting a class definition, add the following to that class definition:

      Parameter XMLKEEPCLASS = 1;

The following shows an example Terminal session:

set r=##class(%SOAP.WSDL.Reader).%New() 
GSOAP>set url="https://devsys/csp/mysamples/GSOP.AddComplexWS.CLS?WSDL=1"
 
GSOAP>d r.Process(url) 
Compilation started on 11/09/2009 12:53:52 with qualifiers 'dk'
Compiling class AddComplex.ns2.ComplexNumber
Compiling routine AddComplex.ns2.ComplexNumber.1
Compilation finished successfully in 0.170s.
 
Compilation started on 11/09/2009 12:53:52 with qualifiers 'dk'
Compiling class AddComplex.AddComplexSoap
Compiling routine AddComplex.AddComplexSoap.1
Compiling class AddComplex.AddComplexSoap.Add
Compiling routine AddComplex.AddComplexSoap.Add.1
Compilation finished successfully in 0.363s.

The WSDL URL is part of a web application, which might be protected by password authentication. For details on using the WSDL in this case, to generate InterSystems IRIS web clients or third-party web clients, see Using a Password-Protected WSDL URL.

In all cases, it is also possible to retrieve the WSDL from a browser after supplying the required username and password, save it as a file, and use the file instead.

Properties to Control Class Generation and Compilation

%SOAP.WSDL.ReaderOpens in a new tab includes the following properties which you can set in order to specify the types of classes to generate from the WSDL.

MakeClient

Specifies whether to generate client classes.

MakeService

Specifies whether to generate an InterSystems IRIS web service based on the WSDL.

CompileClasses

Specifies whether to compile classes after generating them.

If CompileClasses is 1, you can control the behavior of the compiler by specifying flags in the CompileFlags property. For more information, execute the following command:

 Do $System.OBJ.ShowFlags()
ClientPackage

Specifies the package name for the web client and any generated classes.

The default package name is the service name.

If you specify an existing package name, the tool overwrites any existing class that has the same name as a newly generated class by default.

MakeEnsembleClasses

Specifies whether to generate a business operation and related request and response message classes, which you can use in a production.

See Creating Web Services and Web Clients in Productions.

If MakeEnsembleClasses is 1, you must also specify the following propperties:

  • OperationPackage — Package name for the business operation class.

  • RequestPackage — Package name for the request message class.

  • ResponsePackage — Package name for the response message class.

Properties to Control Class Details

%SOAP.WSDL.ReaderOpens in a new tab includes the following properties to control details of the classes generated from the WSDL:

MakeNamespace

Specifies whether the generated classes should include the NAMESPACE class parameter set equal to the namespace of the web service.

  • If the WSDL explicitly indicates the namespace to which a given type belongs, MakeNamespace should be 1. In this case, the generated type class includes the NAMESPACE class parameter set equal to that namespace.

  • If the WSDL does not indicate the namespace for a given type, MakeNamespace can be either 1 or 0.

MakeMessageStyle

Specifies whether to use an unwrapped message format for the methods in the generated web client. This option affects only methods that have SoapBindingStyle equal to "document".

If either of the following statements are true of the WSDL, specify MakeMessageStyle as 1:

  • The <message> elements contain multiple parts.

  • The types used by the response messages belong to multiple namespaces.

Alternatively, the code generation fails and displays an error message such as the following:

ERROR #6425: Element 'wsdl:binding:operation:msg:input' - message 'AddSoapOut' 
Message Style must be used for document style message with 2 or more parts.

For more information, see Using InterSystems IRIS Web Client Classes.

NoArrayProperties

Specifies whether to generate array properties.

If this property is 1, the system does not generate array properties but instead generates another form. For more information, see Creation of Array Properties.

GenerateXMLNIL

Specifies whether to specify the XMLNIL property parameter for applicable properties in the generated classes.

This option applies to each property that corresponds to an XML element that is specified with nillable="true". If this property is 1, the system adds XMLNIL=1 to the property definition. Otherwise, it does not add this parameter.

For details on this property parameter, see Handling Empty Strings and Null Values.

GenerateXMLNILNOOBJECT

Specifies whether to specify the XMLNILNOOBJECT property parameter for applicable properties in the generated classes.

This option applies to each property that corresponds to an XML element that is specified with nillable="true". If this property is 1, the system, the system adds XMLNILNOOBJECT=1 to the property definition. Otherwise, it does not add this parameter. For details on this parameter, see Handling Empty Strings and Null Values.

NoSequence

Specifies whether to set the XMLSEQUENCE class parameter in the generated classes to 0.

By default, the system sets this parameter to 1 in the generated classes, which ensures that the classes respect the order of elements as given in the schema in the WSDL. This value is useful when the schema has multiple elements of the same name within a given parent. For details, see Handling a Document with Multiple Tags with the Same Name.

IgnoreNull

Specifies whether the generated classes should include the XMLIGNORENULL class parameter set to 1.

If you select this option, the system adds XMLIGNORENULL=1 to the class definitions, including the generated web client (or web service). Otherwise, it does not add this parameter.

For details on this class parameter, see Handling Empty Strings and Null Values.

BinaryAsStream

Specifies whether to generate a property of type %Stream.GlobalBinaryOpens in a new tab for each element of type xsd:base64Binary.

If this property is 1, the generated properties are of type %Stream.GlobalBinaryOpens in a new tab. Alternatively, the properties are of type %xsd.base64BinaryOpens in a new tab.

%SOAP.WSDL.ReaderOpens in a new tab ignores any attributes of type xsd:base64Binary.

SecurityInParameter

Specifies the value of the SECURITYIN class parameter in the generated client class.

If you are using Web-Services security, use REQUIRE or ALLOW, depending on whether you want the client to require the elements or simply validate them. Otherwise, IGNORE or IGNOREALL is generally suitable. For details, see Validating WS-Security Headers.

The SECURITYIN parameter is ignored if there is a security policy in an associated (and compiled) configuration class. See Securing Web Services.

Using the Generated Web Client Classes

As noted in the previous section, after you generate an InterSystems IRIS web client class, you do not usually edit the generated class. Instead you write code that creates an instance of that web client and that provides provide client-side error handling. In this code, do the following:

  1. Create an instance of the web client class.

  2. Set its properties. Here you can control items such as the following:

    • Endpoint of the web client (the URL of the web service it uses). To control this, set the Location property, which overrides the LOCATION parameter of the web client class.

    • Settings that designate a proxy server.

    • Settings that control HTTP Basic authentication.

    See the next section as well as Fine-Tuning a Web Client in InterSystems IRIS.

  3. Invoke the methods of the web client as needed.

  4. Perform client-side error handling. See SOAP Fault Handling.

  5. Optionally examine the HTTP response received by the web client, as described later in this topic.

The following shows a simple example, from a session in the Terminal:

GSOAP>set client=##class(Proxies.CustomerLookupServiceSoap).%New()

GSOAP>set resp=client.GetCustomerInfo("137")
 
GSOAP>w resp
 
11@Proxies.CustomerResponse

GSOAP>w resp.Name
Smith,Maria

Example 1: Using the Client That Uses Wrapped Messages

In this example, we create a wrapper class for a web client that uses wrapped messages. To use the example GSOAPClient.AddComplex.AddComplexSoap shown previously, we could create a class like the following:

Class GSOAPClient.AddComplex.UseClient Extends %RegisteredObject
{

ClassMethod Add(arg1 As ComplexNumber, arg2 As ComplexNumber) As ComplexNumber
{
    Set client=##class(AddComplexSoap).%New()
    //uncomment the following to enable tracing
    //set client.Location="https://devsys:8080/csp/mysamples/GSOP.AddComplexWS.cls"
    Set ans=client.Add(arg1,arg2)
    Quit ans 
}

}

The client application would invoke this method in order to execute the web method.

Example 2: Using the Client That Uses Unwrapped Messages

In this example, we create a wrapper class for a web client that uses unwrapped messages. To use the example GSOAPClient.AddComplex.AddComplexSoap shown previously, we could create a class like the following:

Class GSOAPClient.AddComplexUnwrapped.UseClient Extends %RegisteredObject
{

ClassMethod Add(arg1 As GSOAPClient.AddComplexUnwrapped.s0.ComplexNumber, 
arg2 As GSOAPClient.AddComplexUnwrapped.s0.ComplexNumber) 
As GSOAPClient.AddComplexUnwrapped.s0.ComplexNumber
{
    //create the Add message
    Set addmessage=##class(GSOAPClient.AddComplexUnwrapped.s0.Add).%New()
    Set addmessage.a = arg1
    Set addmessage.b = arg2

    Set client=##class(AddComplexSoap).%New()
    
    //send the Add message to client and get response
    Set addresponse=client.Add(addmessage)
    
    //get the result from the response message
    Set ans=addresponse.AddResult
    
    Quit ans
 
}

}

The method has the signature that would typically be expected; that is, it accepts two complex numbers and returns a complex number. The method creates the message that the web client expects. The elements of this message are the two complex numbers.

As you can see, when the web client uses unwrapped messages, it is necessary to write slightly more code to convert arguments in a user-friendly form into the message used by the web client.

Modifying the Generated Client Classes

After you generate an InterSystems IRIS web client class, you do not usually edit the class. Instead you write code that creates an instance of the web client and that provides provide client-side error handling. This section documents the notable exceptions where you do modify the generated client class.

Also see Additional Notes on Web Methods in the Generated Class and Fine-Tuning a Web Client in InterSystems IRIS.

Note:

Do not create a subclass of the generated web client class. The compiler will not generate the supporting classes that it would need in order to run properly, and your subclass would not be usable.

Adjusting the Generated Classes for Extremely Long Strings

In rare cases, you might need to edit the generated client class to accommodate extremely long strings or binary values — values whose lengths exceed the string length limit.

When generating a web client from a WSDL, InterSystems IRIS assumes that any string-type input or output can be represented in InterSystems IRIS as %StringOpens in a new tab, which is not always true. In rare cases, a string might exceed the string length limit. Similarly, InterSystems IRIS assumes that any input or output with XML type base64Binary can be represented in InterSystems IRIS as %xsd.base64BinaryOpens in a new tab), which is not always true, due to the same string length limitation. In neither case does the WSDL contain any information to indicate that this input or output could exceed the string length limit.

When your web client encounters a string or a binary value that is too long, it throws one of the following errors:

  • A <MAXSTRING> error

  • A datatype validation error:

    ERROR #6232: Datatype validation failed for tag your_method_name ...
    

    (This error, of course, can also be caused by a datatype mismatch.)

The problem, however, is easy to correct: adjust the method signature in your generated web client class (specifically the class that inherits from %SOAP.WebClientOpens in a new tab) to use an appropriate stream class:

For example, consider a web service (MyGiantStringService) that has one method (WriteIt), which takes no arguments and returns a very long string. The web client class originally looks something like this:

Class GetGiantString.MyServiceSoap Extends %SOAP.WebClient
{

Method WriteIt() As %String 
[Final,SoapBindingStyle=document,SoapBodyUse=literal,WebMethod]
{
 Quit ..WebMethod("WriteIt").Invoke($this,"https://tempuri.org/MyApp.MyGiantStringService.WriteIt")
}

}

In this case, there is only one adjustment to make. Change the return type of WriteIt as follows:

Method WriteIt() As %GlobalCharacterStream 
[Final,SoapBindingStyle=document,SoapBodyUse=literal,WebMethod]
{
 Quit ..WebMethod("WriteIt").Invoke($this,"https://tempuri.org/MyApp.MyGiantStringService.WriteIt")
}

When you compile this class, the system automatically regenerates the associated classes as needed.

You may also need to adjust property types within any generated type classes. For example, suppose the web service uses an element called <Container>, which includes an element <ContainerPart> of type string. When you generate the InterSystems IRIS web client classes, the system creates a Container class with a ContainerPart property of type %StringOpens in a new tab. If the web service sends a string longer than the string length limit in the <ContainerPart> element, your web client throws an error. To avoid this error, change the type of the ContainerPart property to %GlobalCharacterStreamOpens in a new tab.

Other Adjustments

If the WSDL does not specify the location of the web service, the generated web client does not specify the LOCATION parameter. This is a rare scenario. In this scenario, edit the web client class to include the LOCATION parameter. For example:

Parameter LOCATION = "https://devsys/csp/mysamples/GSOP.AddComplexWS.cls";

Or specify the Location property of your web client instance as shown later in this topic.

You might need to adjust other parameters of the web client class to make other changes. See Fine-Tuning a Web Client in InterSystems IRIS for details.

Adjusting Properties of a Web Client Instance

When you use an instance of your web client classes, you can specify properties of that instance to control its behavior. This section discusses the properties that are most commonly set, as well as their default values.

Changing the Endpoint for the Web Client

When you generate web client, the class automatically specifies the LOCATION parameter as the URL of the web service with which it communicates.

To override this, set the Location property of your web client instance. If Location is null, then the LOCATION parameter is used.

A common usage is to set the Location property to use a different port, in order to enable tracing. For example, suppose that in the generated web client class, the endpoint is defined as follows:

Parameter LOCATION = "https://devsys/csp/mysamples/GSOP.AddComplexWS.cls";

When you use this client, you can include the following line:

   Set client.Location="https://devsys:8080/mysamples/mysamples/GSOP.AddComplexWS.cls"
Note:

If the WSDL does not specify the location of the web service, the generated web client does not specify the LOCATION parameter. This is a rare scenario. In this scenario, either edit the web client class to include the LOCATION parameter or specify the Location property of your web client instance as shown here.

Configuring the Client to Use SSL

If the endpoint for a web client has HTTPS protocol, the web client must be configured to use SSL. Specifically:

  • If you have not already done so, use the Management Portal to create an SSL/TLS configuration that contains the details of the needed SSL connection. For information, see About Configurations in the TLS Guide.

  • Set the SSLConfiguration property of the web client equal to that SSL/TLS configuration name.

Note that if the client is connecting via a proxy server, you must also set the HttpProxySSLConnect property equal to 1 in the web client. For information on configuring an InterSystems IRIS web client to use a proxy server, see Fine-Tuning the Web Client.

Specifying the SOAP Version

The generated web client automatically specifies the SOAP version to use in request messages, based on the SOAP version in the WSDL of the web service. Specifically it sets the SOAPVERSION parameter.

To override this, set the SoapVersion property of your web client instance. Use one of the following values:

  • "" — The client sends SOAP 1.1 messages.

  • "1.1" — The client sends SOAP 1.1 messages.

  • "1.2" — The client sends SOAP 1.2 messages.

If SoapVersion is null, then the SOAPVERSION parameter is used.

Other Adjustments

You might need to set other properties of the web client instance to make other changes. See Fine-Tuning a Web Client in InterSystems IRIS for details.

Using the HTTP Response

By default, when you invoke a web client method, you do so via HTTP. The HTTP response is then available as the HttpResponse property of the web client instance. This property is an instance of %Net.HttpResponseOpens in a new tab, which in turn has properties like the following:

  • Headers contains the headers of the HTTP response.

  • Data is an InterSystems IRIS multidimensional array that contains any data in the HTTP response.

  • StatusCode, StatusLine, and ReasonPhrase provide status information.

For details, see Using Internet Utilities or see the class documentation for %Net.HttpResponseOpens in a new tab.

FeedbackOpens in a new tab