Skip to main content

Defining Custom Processing in a Web Service

In rare scenarios, it may be useful to define an InterSystems IRIS® data platform web service that uses custom processing to handle inbound messages and to build response messages. In these scenarios, you implement either the ProcessBodyNode() method or the ProcessBody() method in the web service. This topic provides the details.

Overview

In custom processing, you parse the inbound message and construct the response manually. The requirements are as follows:

  • In the web service, you define web methods that have the desired signatures. You do this to establish the WSDL of the web service. These web methods (or some of them) can be stubs. A method is executed only if ProcessBodyNode() or ProcessBody() returns 0.

  • Also in the web service, you implement one of the following methods:

    • ProcessBodyNode() — This method receives the SOAP body as an instance of %XML.NodeOpens in a new tab. You can use InterSystems IRIS XML tools to work with this instance and build the response message. The SOAP envelope is available in the Document property of this instance of %XML.NodeOpens in a new tab.

    • ProcessBody() — This method receives the SOAP Body as a stream. Because the SOAP body is an XML fragment rather than an XML document, you cannot use the InterSystems IRIS XML tools to read it. Instead, you parse the stream with ObjectScript functions and extract the needed parts.

    If you define both of these methods, the ProcessBodyNode() method is ignored.

In either case, the response message that you construct must be consistent with the WSDL of the web service.

Implementing ProcessBodyNode()

The ProcessBodyNode() method has the following signature:

method ProcessBodyNode(action As %String, body As %XML.Node, 
       ByRef responseBody As %CharacterStream) as %Boolean

Where:

If you implement this method in a web service, the method should do the following:

  1. Examine the action and branch accordingly. For example:

     if action["action1" { 
      //details
     }
  2. If you need to access the SOAP <Envelope> (for example, to access its namespace declarations), use the Document property of body. This equals an instance of %XML.DocumentOpens in a new tab, which represents the SOAP envelope as a DOM (Document Object Model).

    Otherwise, use body directly.

  3. Now you have the following options:

    For details, see Using XML Tools. Be sure to check the status returned by methods in these classes, to simplify troubleshooting in the case of an error.

  4. If an error occurs during the processing of the request, return a fault in the usual way using the ReturnFault() method.

  5. Use the Write() method of the response stream to write the XML fragment which will become the child element of <Body>.

  6. If a response stream is created, return 1. Otherwise, return 0, which causes InterSystems IRIS to run the web method associated with the given action.

    For example:

      if action["action1" { 
        //no custom processing for this branch
        quit 0
       } elseif action["action2" {
          //details
          //quit 1
       }

Implementing ProcessBody()

The ProcessBody() method has the following signature:

method ProcessBody(action As %String, requestBody As %CharacterStream, 
                   ByRef responseBody As %CharacterStream) as %Boolean

Where:

If you implement this method in a web service, the method should do the following:

  1. Examine the action and branch accordingly. For example:

     if action["action1" { 
      //details
     }
  2. Use the Read() method of requestBody to obtain the SOAP <Body>. For example:

     set request=requestBody.Read()
    
  3. Parse this stream by using tools such as $EXTRACT. For example:

     set in1="<echoString xmlns=""http://soapinterop.org/xsd""><inputString>"
     set in2="</inputString></echoString>"  
     set contents=$extract(request,$length(in1)+1,*-$length(in2))
  4. If an error occurs during the processing of the request, return a fault in the usual way using the ReturnFault() method.

  5. Use the Write() method of the response stream to write the XML fragment that will become the child element of <Body>. For example:

     set in1="<echoString xmlns=""http://soapinterop.org/xsd""><inputString>"
     set in2="</inputString></echoString>"  
     set request=requestBody.Read()
     if ($extract(request,1,$length(in1))'=in1) || ($extract(request,*-$length(in2)+1,*)'=in2) {
       do responseBody.Write("Bad Request: "_request)
       quit 1
     }
    
     set out1="<echoStringResponse xmlns=""http://soapinterop.org/xsd""><echoStringResult>"
     set out2="</echoStringResult></echoStringResponse>"
     do responseBody.Write(out1)
     do responseBody.Write($extract(request,$length(in1)+1,*-$length(in2)))
     do responseBody.Write(out2)
  6. If a response stream is created, return 1. Otherwise, return 0, which causes InterSystems IRIS to run the web method associated with the given action.

FeedbackOpens in a new tab