Web Services changes

There are changes in support of web services in Genero 3.20.

XML serializer is case sensitive

From FGLGWS 3.20 on, the XML serializer is case sensitive, same as the JSON serializer. This means that the serializer uses the case of the variable name as defined in the 4GL file.

What impact has this on my existing Web services? It is recommended to:

  1. Generate a new client and server stub via the fglwsdl tool.
    • The tool has an enhancement which does not generate XMLName attributes, unless they are really needed.
    • If you do not generate the stub, the XMLName attribute is still taken into account, so it should not have any impact.
  2. Check on server sides that all published SOAP web services input and output records are in lower case. This ensures compatibility with older versions. If backward compatibility is not an issue, then you must query the server WSDL file and generate the client stub from it.

For more details, see Customizing XML serialization.

Control HTTP Date header for GET, HEAD and DELETE requests

Starting with GWS 3.20.00, the FGLPROFILE entry http.global.request.date can be used to control whether GWS HTTP GET, HEAD and DELETE requests must send the HTTP Date header.

For more details, see HTTP configuration.

Support for empty HTTP POST or PUT requests

GWS 3.20.01 allows now to POST or PUT empty requests and read them on server side:
DEFINE req com.HTTPRequest
LET req = com.HTTPRequest.Create("http://tempuri.org")
CALL req.setMethod("POST") # or PUT
CALL req.doRequest()

Prior to GWS 3.20.01, the doRequest() call returned error code -15555 and the error message "Unsupported request-response feature".

The server side can now read empty POST or PUT requests as well. For instance in the following code sample, the return value of readTextRequest() will be NULL:
DEFINE ser com.HTTPServiceRequest
DEFINE txt STRING
LET ser = com.WebServiceEngine.getHttpServiceRequest(-1)
IF ser.getMethod() == "POST" THEN
  LET txt = ser.readTextRequest()
  IF txt IS NULL THEN
    DISPLAY "No body"
  END IF
END IF

Notice that the Content-Type is still checked and may raise an error, if it doesn't match. So using readXmlRequest() must have a Content-Type of XML format, even if the body is empty. In practice, it is recommended to check the Content-Type before doing any read operation.

For more details, see com.HTTPRequest.doRequest.

New high-level RESTful framework

Genero BDL 3.20 provides a new framework for RESTful Web services programming.

See RESTful Web services with high-level framework.

Changes to security.global.protocol in FGLPROFILE

Starting with FGLGWS 3.20.07 GWS secured communication is based on the OpenSSL 1.1 engine. This version of OpenSSL always selects the security protocol. It no longer allows you to specify a specific Transport Layer Security (TLS) or Secure Sockets Layer (SSL).

The security.global.protocol entry in the fglprofile file is therefore no longer supported.

For instance, if you have set security.global.protocol = "TLsv1.2" to configure OpenSSL to use TLSv1.2 for HTTPS for earlier versions, you may encounter the following error message in your Web service:
OpenSSL 1.1 doesn't support specific protocol anymore
It is therefore recommended to remove the security.global.protocol entry from your fglprofile file. For more information on Web service security configuration see Web Services FGLPROFILE configuration.

XMLChoice attribute nested option

The fglwsdl tool now supports the attribute XMLChoice="nested" option to produce an XML representation supporting a substitutionGroup. A substitutionGroup in an XML schema is where one XML element can be replaced by another element that has a substitutionGroup with the same name.

This change applies if you have previously used XMLChoice for a WSDL containing a substitutionGroup. In the following XSD schema example, the "name" element, can be represented as a simple string type (simple-name) or as a more complex type (full-name).
<xs:element name="name" />
<xs:element name="simple-name" type="xs:string" substitutionGroup="name" />
<xs:element name="full-name" substitutionGroup="name">
  <xs:complexType>
    <xs:all>
      <xs:element name="first" type="xs:string" minOccurs="0"/>
      <xs:element name="middle" type="xs:string" minOccurs="0"/>
      <xs:element name="last" type="xs:string"/>
    </xs:all>
  </xs:complexType>
</xs:element>

<xs:element name="Identity"/>
  <xs:sequence>
    <xs:element ref="name"/>
  </xs:sequence>
</xs:element>

Previous versions using XMLChoice

In previous versions, the generated stub for a record with XMLChoice generated only one value for all available choices.
DEFINE Identity RECORD ATTRIBUTE(XMLSequence,XMLName="Identity")
         name RECORD ATTRIBUTE(XMLChoice)
           _SELECTOR_ SMALLINT ATTRIBUTE(XMLSelector),
           name STRING,
           simple_name STRING,
           full_name RECORD ATTRIBUTE(XMLAll)
             first STRING ATTRIBUTE(XMLOptional),
             middle STRING ATTRIBUTE(XMLOptional),
             last STRING 
           END RECORD
         END RECORD
       END RECORD

New version, using XMLChoice="nested"

In the new version, by setting XMLChoice="nested" on the variable, you can choose at runtime one of the available options; name, simple-name, or full-name.
Note: In the example the first name (the substitutionGroup tag), is not serialized in XML.
The attribute can be used with a BDL RECORD defined to specify the XML representation for the schema as in the example:
DEFINE Identity RECORD ATTRIBUTE(XMLSequence,XMLName="Identity")
         name RECORD ATTRIBUTE(XMLChoice="nested")
           _SELECTOR_ SMALLINT ATTRIBUTE(XMLSelector),
           name STRING,
           simple_name STRING ATTRIBUTE(XMLName="simple-name"),
           full_name RECORD ATTRIBUTE(XMLAll,XMLName="full-name")
             first STRING ATTRIBUTE(XMLOptional),
             middle STRING ATTRIBUTE(XMLOptional),
             last STRING 
           END RECORD
         END RECORD
       END RECORD
This is an example of the XML representation when the _SELECTOR_ value is 3:
<Identity>
  <full-name>
     <first>John</first>
     <last>Smith</last>
  </full-name>
</Identity>
This is an example of the XML representation when the _SELECTOR_ value is 2:
<Identity>
  <simple-name>John Smith</simple-name>
</Identity>
Important: If in versions prior to GWS 3.20 you had a variable that was expected to serialize an XMLChoice value, you can set XMLChoice="nested" attribute on that variable to improve the serialization options and to avoid serializer errors.
It is therefore recommended to do the following:
  • Recompile the Genero Web Service server to create a new WSDL that supports the XML XMLChoice="nested" feature.
  • Regenerate all Genero Web Service client stubs from the newly-generated WSDL to get the support of XMLChoice="nested". Regenerate client stubs using the fglwsdl tool.