Message Transmission Optimization Mechanism (MTOM)

The W3C Message Transmission Optimization Mechanism (MTOM) is a method of efficiently sending binary data to and from Web services.

When to use MTOM

Use MTOM when you have a Web service transmitting large documents. MTOM must be used when you have to optimize the transfer of binary data located in a BLOB. Any 4GL BYTE will be transferred as an HTTP part over the wire. Nothing changes from the programmer perspective: the program manipulates a 4GL BLOB on the client side as well as on the server side. The programmer may not even know that an HTTP part was used.

MTOM and a GWS server application

If you are creating a server application from scratch, use setFeature to enable MTOM. See Enabling MTOM on the server side.

If you are using the -s option of the fglwsdl command to generate the server stubs, you can also use the -mtom option of the fglwsdl command to override the WS-Policy; you normally do not have to override the WS-Policy. See fglwsdl.

MTOM and a GWS client application

For a GWS client, if the Web service enabled MTOM, then the generated WSDL should include the MTOM policy and it should work transparently. If the MTOM policy is not included in the WSDL and you know that the Web service is using MTOM, you can force the generation of stubs with MTOM support by with the -mtom option of the fglwsdl command. The -mtom option is only needed if you want to override the WS-Policy; you normally do not have to override the WS-Policy. See fglwsdl.

Optimization Layer 1: Using MTOM

Optimization has layers.

When MTOM is used, GWS manages the large documents using BYTE variables. When MTOM is enabled, a 4GL BLOB is transmitted transparently via a HTTP attachment. Your Genero program receives a BLOB variable, filled as before, oblivious to how the content was transmitted. It is "seen" as a BYTE, as if it was inline.

Optimization Layer 2: Using STRING variables

In addition to enabling MTOM, you can further optimize by using STRING variables instead of BYTE variables.
Note: A BYTE variable contains the data value, located in memory. A STRING variable contains the path to a file.
The -hexb64AsString option of the fglwsdl command forces the stub generation with STRING instead of BYTE.
For example, you can avoid loading a big file into a BYTE entirely in memory. Instead of doing this:
DEFINE req RECORD
   data BYTE
END RECORD
DEFINE resp RECORD
   data2 BYTE
END RECORD
LOCATE req.data IN MEMORY
LOCATE resp.data2 IN MEMORY
CALL rec.data.readFile("myfile.jpg")
... Do SOAP Operation
CALL resp.data2.writeFile("retfile.jpg")
You can do this:
DEFINE req RECORD
   data STRING ATTRIBUTES(XMLOptimizedContent)
END RECORD
DEFINE resp RECORD
   data2 STRING ATTRIBUTES(XMLOptimizedContent)
END RECORD
LET rec.data = "myfile.jpg"
... Do SOAP Operation
handle returned file at resp.data2