Skip to main content
Previous sectionNext section

Creating SOAP Web Services

This topic describes the basics of how to create a web service in InterSystems IRIS. It includes the following topics:

See the first topic for a table that summarizes the URLs related to your web service.

Overview of InterSystems IRIS Web Services

To create a web service in InterSystems IRIS, you create a class that extends %SOAP.WebService, which provides all the functionality required to make one or more methods callable via the SOAP protocol. In addition, this class automates the management of SOAP-related bookkeeping, such as maintaining a WSDL document that describes a service.

Basic Requirements

To create a web service in InterSystems IRIS, create and compile an InterSystems IRIS class that meets the following basic requirements:

  • The class must extend %SOAP.WebService.

  • The class must define the SERVICENAME parameter. InterSystems IRIS does not compile the class unless it defines this parameter.

  • This class should define methods or class queries that are marked with the WebMethod keyword.

    Important:

    In most cases, web methods should be instance methods. Within a web method, it is often necessary to set properties of and invoke methods of the web service instance (as described in later topics) to fine-tune the behavior of the method. Because a class method cannot do these tasks, a class method is usually not suitable as a web method.

  • For any web methods, make sure that each value in the method signature has an XML projection. For example, suppose that your method had the following signature:

    Method MyWebMethod(myarg as ClassA) as ClassB [ WebMethod ]
    Copy code to clipboard

    In this case, both ClassA and ClassB must have an XML representation. In most cases, this means that their superclass lists must include %XML.Adaptor; see Projecting Objects to XML. InterSystems IRIS SOAP support provides special handling for collections and streams, as noted after this list.

    The web method can specify the ByRef and Output keywords in the same way that ordinary methods do. (For information on these keywords, see the topic “Methods” in Defining and Using Classes.)

  • Consider the values that are likely to be carried within these arguments and return values. XML does not permit nonprinting characters, specifically characters below ASCII 32 (except for carriage returns, line feeds, and tabs, which are permitted in XML).

    If you need to include any disallowed nonprinting character, specify the type as %Binary, %xsd.base64Binary (which is equivalent), or a subclass. This value is automatically converted to base–64 encoding on export to XML (or automatically converted from base–64 encoding on import).

  • Do not rely on the method signature to specify the default value for an argument. If you do, the default value is ignored and a null string is used instead. For example, consider the following method:

    Method TestDefaults(val As %String = "Default String") As %String [ WebMethod ]
    Copy code to clipboard

    When you invoke this method as a web method, if you do not supply an argument, a null string is used, and the value "Default String" is ignored.

    Instead, at the start of the method implementation, test for a value and use the desired default if applicable. One technique is as follows:

     if arg="" {
       set arg="Default String"
     }
    Copy code to clipboard

    You can indicate the default value in the method signature as usual, but this is purely for informational purposes and does not affect the SOAP messages.

  • For any required arguments in a web method, specify the REQUIRED property parameter within the method signature. For example:

    Method MyWebMethod(myarg as ClassA(REQUIRED=1)) as ClassB [ WebMethod ]
    Copy code to clipboard

By default, any inherited methods are treated as ordinary methods, even if a superclass marks them as web methods (but see “Subclassing an Existing InterSystems IRIS Web Services,” later in this topic).

Input and Output Objects That Do Not Need %XML.Adaptor

In most cases, when you use an object as input or output to a web method, that object must extend %XML.Adaptor. The exceptions are as follows:

  • If the object is %ListOfDataTypes, %ListOfObjects, %ArrayOfDataTypes, %ArrayOfObjects, or a subclass, the InterSystems IRIS SOAP support implicitly treats the object as if it included %XML.Adaptor. You do not need to subclass these classes. However:

    • You must specify ELEMENTTYPE within the method signature, as follows:

      Method MyMethod() As %ListOfObjects(ELEMENTTYPE="MyApp.MyXMLType") [WebMethod]
      {
         //method implementation
      }
      
      Copy code to clipboard

      Or, in the case of an input argument:

      Method MyMethod(input As %ListOfObjects(ELEMENTTYPE="MyApp.MyXMLType")) [WebMethod]
      {
         //method implementation
      }
      
      Copy code to clipboard
    • If the class that you name in ELEMENTTYPE is an object class, it must inherit from %XML.Adaptor.

  • If the object is one of the stream classes, the InterSystems IRIS SOAP support implicitly treats the object as if it included %XML.Adaptor. You do not need to subclass the stream class.

    If it is a character stream, the InterSystems IRIS SOAP tools assume that the type is string. If it is a binary stream, the tools treat it as base-64–encoded data. Thus it is not necessary to supply type information.

Using Result Sets as Input or Output

You can use result sets as input or output, but your approach depends on the intended web clients.

  • If both the web service and client are based on InterSystems IRIS or one is based on .NET, you can use the specialized result set class, %XML.DataSet, which is discussed in the topic “Using Datasets in SOAP Messages.” Or you can use a class query as a web method. The XML representation is automatically the same as for %XML.DataSet.

  • To output results of a query so that a Java-based web client can work with it, use a %ListOfObjects subclass; there is an example in SOAP.Demo in the SAMPLES namespace.

Simple Example

This section shows an example web service, as well as an example of a request message that it can recognize and the corresponding response message.

First, the web service is as follows:

/// MyApp.StockService
Class MyApp.StockService Extends %SOAP.WebService 
{

/// Name of the WebService.
Parameter SERVICENAME = "StockService";

/// TODO: change this to actual SOAP namespace.
/// SOAP Namespace for the WebService
Parameter NAMESPACE = "http://tempuri.org";

/// Namespaces of referenced classes will be used in the WSDL.
Parameter USECLASSNAMESPACES = 1;

/// This method returns tomorrow's price for the requested stock
Method Forecast(StockName As %String) As %Integer [WebMethod]
{
    // apply patented, nonlinear, heuristic to find new price
    Set price = $Random(1000)
    Quit price
}
}
Copy code to clipboard

When you invoke this method from a web client, the client sends a SOAP message to the web service. This SOAP message might look like the following (with line breaks and spaces added here for readability):

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope 
xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' 
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
xmlns:s='http://www.w3.org/2001/XMLSchema'>
  <SOAP-ENV:Body>
    <Forecast xmlns="http://tempuri.org">
     <StockName xsi:type="s:string">GZP</StockName>
    </Forecast>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Copy code to clipboard

Note that the message body (the <SOAP-ENV:Body> element) includes an element named <Forecast>, which is the name of the method that the client is invoking. The <Forecast> includes one element, <StockName>, whose name is based on the argument name of the web method that we are invoking. This element contains the actual value of this argument.

The web service performs the requested action and then sends a SOAP message in reply. The response message might look like the following:

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope 
xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' 
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
xmlns:s='http://www.w3.org/2001/XMLSchema'>
  <SOAP-ENV:Body>
    <ForecastResponse xmlns="http://www.myapp.org">
      <ForecastResult>799</ForecastResult>
    </ForecastResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Copy code to clipboard

These examples do not include the HTTP headers that precede the SOAP message itself.

Creating a Web Service

You can create web services in any of the following ways:

Using the Web Service Wizard

The Web Service Wizard generates a simple stub.

  1. Click File > New.

    This displays the New dialog box.

  2. Click the General tab.

  3. Click New Web Service and then click OK.

    This displays a wizard.

  4. Enter values for the package name, class name, and web service name. These are required.

  5. Optionally edit the namespace URI (or change this initial value later). This is the XML namespace, not the InterSystems IRIS namespace.

  6. Optionally type a list of method names, on separate lines.

  7. Click OK.

Now, you have a new web service class that contains stubs for the web methods. For example:

/// MyApp.StockService
Class MyApp.StockService Extends %SOAP.WebService 
{

/// Name of the WebService.
Parameter SERVICENAME = "StockService";

/// TODO: change this to actual SOAP namespace.
/// SOAP Namespace for the WebService
Parameter NAMESPACE = "http://tempuri.org";

/// Namespaces of referenced classes will be used in the WSDL.
Parameter USECLASSNAMESPACES = 1;

/// TODO: add arguments and implementation.
/// Forecast
Method Forecast() As %String [ WebMethod ]
{
   ;Quit "Forecast"
}

}
Copy code to clipboard

Using the SOAP Wizard with an Existing WSDL

In some cases, the WSDL has been designed already and it is necessary to create a web service that matches the WSDL; this is known as “WSDL-first development.” In InterSystems IRIS, there are three steps to this development:

  1. Use the SOAP Wizard to read the WSDL and to generate the web service and all supporting classes.

    This wizard can also generate web client classes (which is more common).

    For information on using this wizard, see “Using the SOAP Wizard,” later in this book. Follow the steps described in that section and also select the Create Web Service option within the wizard.

    Or use the %SOAP.WSDL.Reader class as described in “Using the %SOAP.WSDL.Reader Class.”

  2. Examine the generated classes to see if you need to change any %String values in the method signatures.

    When the wizard reads a WSDL, it assumes that any string-type input or output can be represented in InterSystems IRIS as %String, which is not always true. In rare cases, some strings might exceed the maximum length string limit.

    See “Adjusting the Generated Classes for Extremely Long Strings,” later in this book.

  3. Edit the methods in the generated web service so that they perform the desired actions.

    Each method is initially a stub like the following example:

    Method Add(a As Test.ns2.ComplexNumber, b As Test.ns2.ComplexNumber) As Test.ns2.ComplexNumber 
    [ Final, SoapAction = "http://www.mynamespace.org/GSOAP.AddComplexWS.Add", 
    SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
    {
     // Web Service Method Implementation Goes Here.
    }
    Copy code to clipboard

    The wizard includes compiler keywords such as Final and SoapBindingStyle. You should not change the values of these keywords.

If the WSDL includes WS-Policy elements, the wizard also generates a configuration class for the web service. The default configuration class name is the web service name, with Config appended to it. For information on WS-Policy, see Securing Web Services.

Subclassing an Existing InterSystems IRIS Web Service

You can create a web service by creating a subclass of an existing InterSystems IRIS web service class and then adding the SOAPMETHODINHERITANCE parameter to your class as follows:

PARAMETER SOAPMETHODINHERITANCE = 1;
Copy code to clipboard

The default for this parameter is 0. If this parameter is 0, your class does not inherit the web methods as web methods. That is, the methods are available as ordinary methods but cannot be accessed as web methods within the web service defined by the subclass.

If you set this parameter to 1, then your class can use web methods defined in any superclasses that are web services.

Specifying Parameters of the Web Service

Make sure that your web service class uses appropriate values for the following parameters.

Note:

If you use the SOAP wizard to generate a web service from an existing WSDL, do not modify any of these parameters.

SERVICENAME

Name of the web service. This name must start with a letter and must contain only alphanumeric characters.

InterSystems IRIS does not compile the class unless the class defines this parameter.

NAMESPACE

URI that defines the target namespace for your web service, so that your service, and its contents, do not conflict with another service. This is initially set to "http://tempuri.org" which is a temporary URI often used by SOAP developers during development.

If you do not specify this parameter, the target namespace is "http://tempuri.org".

For an InterSystems IRIS web service, there is no way to put request messages in different namespaces. An InterSystems IRIS web client, however, does not have this limitation; see “Namespaces for the Messages,” later in this book.

RESPONSENAMESPACE

URI that defines the namespace for the response messages. By default, this is equal to the namespace given by the NAMESPACE parameter.

For an InterSystems IRIS web service, there is no way to put response messages in different namespaces. An InterSystems IRIS web client, however, does not have this limitation; see “Namespaces for the Messages,” later in this book.

TYPENAMESPACE

Namespace for the schema for the types defined by the web service. If you do not specify this parameter, the schema is in the target namespace of the web service (that is, either NAMESPACE or the default, which is "http://tempuri.org").

For an InterSystems IRIS web service, there is no way to put the request message types in different namespaces. An InterSystems IRIS web client does not have this limitation; see “Namespaces for Types,” later in this book.

RESPONSETYPENAMESPACE

URI that defines the namespace for types used by the response messages. By default, this is equal to the namespace given by the TYPENAMESPACE parameter.

This parameter is used only if SoapBindingStyle equals "document" (the default).

For either an InterSystems IRIS web service or an InterSystems IRIS web client, the types for the response messages must all be in the same namespace.

SOAPVERSION

Specifies the SOAP version or versions advertised in the WSDL of the web service. Use one of the following values:

  • "" — Use this value for SOAP 1.1 or 1.2.

  • "1.1" — Use this value for SOAP 1.1. This is the default.

  • "1.2" — Use this value for SOAP 1.2.

When the web service receives a SOAP request, the SoapVersion property of the web service is updated to equal the SOAP version of that request.

See also “Restricting the SOAP Versions Handled by a Web Service,” later in this book.

For details on how these values affect the WSDL, see the topic “Details of the Generated WSDLs.”

About the Catalog and Test Pages

When you compile a web service class, the class compiler generates a convenient catalog page that you can use to examine the web service. This catalog page provides a link to a simple, limited test page (also generated). These pages are disabled by default. Enable them only in a test environment.

Access to the Catalog and Test Pages

If there is no web application for the namespace you are using, you cannot access the catalog and test pages; see “InterSystems IRIS Web Service as Part of a Web Application” in the previous topic. Also, by default, these pages are inaccessible. To enable access to them, open the Terminal, go to the %SYS namespace, and enter the following commands:

set ^SYS("Security","CSP","AllowClass",webapplicationname,"%SOAP.WebServiceInfo")=1
set ^SYS("Security","CSP","AllowClass",webapplicationname,"%SOAP.WebServiceInvoke")=1
Copy code to clipboard

Where webapplicationname is the web application name with a trailing slash, for example, "/csp/mynamespace/".

You can use these pages only if you are logged in as a user who has USE permission for the %Development resource.

Displaying the Catalog and Test Pages

The URL for the catalog page is constructed as follows:

base/csp/app/web_serv.cls
Copy code to clipboard

Here base is the base URL for your web server (including port if necessary), /csp/app is the name of the web application in which the web service resides, and web_serv is the class name of the web service. (Typically, /csp/app is /csp/namespace.) For example:

http://localhost:52773/csp/samples/MyApp.StockService.cls
Copy code to clipboard

Notes on These Pages

The catalog page displays the class name, namespace, and service name, as well as the comments for the class and web methods. The Service Description link displays the generated WSDL; for information, see the section “Viewing the WSDL,” later in this topic. The page then lists the web methods, with links (if you have the suitable permissions). The link for a given method displays a test page where you can test that method in a limited fashion.

Notes about this test page:

  • It does not enable you to see the SOAP request.

  • It does not test the full SOAP pathway. This means, for example, it does not write to the SOAP log that is discussed later in this topic.

  • It accepts only simple, literal inputs, so you cannot use it to call methods whose arguments are objects, collections, or datasets.

This book does not discuss this page further. To test your web service more fully, generate and use a web client as described later in this book.

Viewing the WSDL

When you use %SOAP.WebService to define a web service, the system creates and publishes a WSDL document that describes this web service. Whenever you modify and recompile the web service, the system automatically updates the WSDL correspondingly. This section discusses the following:

Also see “WSDL Support in InterSystems IRIS” in the first topic.

Important:

By definition, a web service and its web clients are required to comply to a common interface, regardless of their respective implementations (and regardless of any underlying changes in technology). A WSDL is a standards-compliant description of this interface. It is important to note the following:

  • In practice, a single SOAP interface can often be correctly described by multiple, slightly different WSDL documents.

    Accordingly, the WSDL generated by InterSystems IRIS may have a slightly different form depending on the version of InterSystems IRIS. It is beyond the scope of this documentation to describe any such differences. InterSystems can commit only to the interoperability of web services and their respective clients, as required in the W3C specifications.

  • The W3C specifications do not require that either a web service or a web client be able to generate a WSDL to describe the interface with which it complies.

    The system generates the WSDL document and serves it at a specific URL, for convenience. However, if the containing web application requires password authentication or requires an SSL connection, you may find it impractical to access the WSDL in this way. In such cases, you should download the WSDL to a file and use the file instead. Also, as noted previously, the generated WSDL does not contain any information about SOAP headers added at runtime. If you need a WSDL document to contain information about SOAP headers added at runtime, you should download the WSDL to a file, modify the file as appropriate, and then use that file.

Viewing the WSDL

To view the WSDL for the web service, use the following URL:

base/csp/app/web_serv.cls?WSDL
Copy code to clipboard

Here base is the base URL for your web server (including port if necessary), /csp/app is the name of the web application in which the web service resides, and web_serv is the class name of the web service. (Typically, /csp/app is /csp/namespace.)

Note:

Any percent characters (%) in your class name are replaced by underscore characters (_) in this URL.

For example:

http://localhost:52773/csp/samples/MyApp.StockService.cls?WSDL
Copy code to clipboard

The browser displays the WSDL document, for example:

generated description: wsdl

Important:

Not all browsers display the schema correctly. You might need to view the page source to see the actual schema. For example, in Firefox, right-click and then select View Source.

Generating the WSDL

You can also generate the WSDL as a static document. The %SOAP.WebService class provides a method you can use for this:

FileWSDL()
ClassMethod FileWSDL(fileName As %String, includeInternalMethods As %Boolean = 1) As %Status 
Copy code to clipboard

Where fileName is the name of the file, and includeInternalMethods specifies whether the generated WSDL includes any web methods that are marked as Internal.

Suppressing Internal Web Methods from the WSDL

If the web service has web methods that are marked as Internal, by default the WSDL includes these web methods. You can prevent these methods from being included in the WSDL. To do so, do either of the following:

  • Use the FileWSDL() method of the web service to generate the WSDL; see the previous section. This method provides an argument that controls whether the WSDL includes internal web methods.

  • Specify the SOAPINTERNALWSDL class parameter as 0 in the web service class. (The default for this class parameter is 1.)