Multipart requests or responses

In GWS REST there is support for the standard multiple part message, in which one or more different sets of data are combined in a single body.

You can specify an HTTP multipart request or response for transferring data of several MIME types, such as JSON, XML, simple string, and to upload or download files.

Multipart/form-data support

In the multipart/form-data type, entire files can be included in the data transfer without encoding. This is ideally suited for uploading and downloading image or text files to a Web service.

Separate parts are identified by the GWS REST engine's naming convention sequence for headers and body parts that start with "rv0" and goes to the "rvnth" number of parts. You can change default header naming by adding a value in the WSName attribute to your parameter.

The GWS REST engine also creates a "boundary" string in the "Content-Type: " header. This boundary, is placed between the various parts, and at the beginning and end of the body of the message.

Define multipart request body

You automatically define a multipart request body when you have an input parameter without any of the REST parameter attributes (WSHeader, WSQuery, WSCookie).
Important:

A message body is required when you perform an HTTP PUT or POST request to a resource, otherwise the request results in the error-9106.

If you have more than one input parameter without a REST attribute, the GWS treats the request as a multipart of form-data type. The example is of a multipart request function. The input parameter values "addressfld1" and "date2" are sent in separate parts in the request body:
IMPORT com
IMPORT util

PUBLIC DEFINE myError RECORD ATTRIBUTE(WSError="My error")
  code INTEGER,
  reason STRING
END RECORD

PUBLIC FUNCTION updateUsersAddress(
    id INTEGER ATTRIBUTES(WSParam),
    addressfld1 STRING,
    date2 STRING)
  ATTRIBUTES(WSPut,
             WSPath="/users/{id}",
             WSDescription="Update user address and date updated field",
             WSThrows="400:@myerror")
  RETURNS STRING
    DEFINE ret STRING
    DEFINE dt DATETIME YEAR TO SECOND
    LET dt = util.Datetime.parse(date2, "%Y-%m-%d %H:%M:%S" )
    IF (dt IS NULL) THEN
        LET ret = "Invalid date"
    ELSE  
       WHENEVER ERROR CONTINUE
       UPDATE course2 SET users_address= addressfld1, date_updated=dt
             WHERE @users_id = id
       WHENEVER ERROR STOP
       CASE
       WHEN SQLCA.SQLCODE == 0
          LET ret = SFMT("Updated user with ID: %1",id)
       WHEN SQLCA.SQLCODE == NOTFOUND
          LET ret = SFMT("No resource found for ID:  %1",id)
       OTHERWISE
         LET myError.reason = SFMT("SQL error:%1 [%2]",SQLCA.SQLCODE, SQLERRMESSAGE)
         CALL com.WebServiceEngine.SetRestError(400,myError)
       END CASE
    END IF
    RETURN ret
END FUNCTION

Define multipart response body

Similar to the request, there is one response body per return value which does not have a REST attribute. A notable difference is that only the WSHeader attribute is allowed in responses. If there are more than one return values without WSHeader attributes, the multipart is of type form-data.
Important:

A message body in the response is required when you perform an HTTP GET, POST, PUT, DELETE operation on a resource, otherwise the response results in the error-9106.

This is a multipart response sample REST function. The string return value is not defined with a WSHeader attribute and its value is therefore sent in the response body:
PUBLIC FUNCTION help()
  ATTRIBUTES (WSGet,
              WSPath="/help")
  RETURNS (INTEGER ATTRIBUTE(WSHeader), STRING)
    RETURN 3, "hello world"
END FUNCTION