Skip to content

JSON Support

The Web Framework uses web services to communicate between client and server. The web services exchange data in JSON format. To support this, we now support JSON-In (requests to the web server) as well as JSON-out (responses from the web server).

Prior to version 17.1, we supported the following web-service data exchange formats:

POST: SOAP/xml-in, SOAP/xml-out

Example:

POST: http://localhost/OrderEntry/TestService.wso
- The SOAP/xml data is passed in with a request content type of text/xml. - The response data is returned as SOAP/xml with a response content type of text/xml.

This is the only option that allows you to pass in complex data types (arrays, structs). This is the standard web-service SOAP call.

POST: urlencoded-in, JSON-out

Example:

POST: http://localhost/OrderEntry/TestService.wso/JSON
- The request content type is application/x-www-form-url-encoded. - The method name is passed in the first trailing path, "JSON" is passed in the second trailing path, and the data is passed in the post as URL-encoded name/value pairs. - The response data is returned as JSON with a content type of application/json.

This can only be used to pass in simple parameter types.

GET: query-string in, JSON-out

Example:

GET: http://localhost/OrderEntry/TestService.wso/SayHello/JSON?sName=John
- The method name is passed in as the first trailing path, "JSON" is passed in the second trailing path, and parameters are passed in the query string as name/value pairs. - The response data is returned as JSON with a content type of application/json.

This can only be used to pass in simple parameter types.

POST: urlencoded-in, XML-out

Example:

POST: http://localhost/OrderEntry/TestService.wso
- The request content type is application/x-www-form-url-encoded. - The method name is passed in the first trailing path, and the data is passed in the post as URL-encoded name/value pairs. - The response data is returned as bare XML (no SOAP envelope) with a content type of text/xml.

This can only be used to pass in simple parameter types.

GET: query-string in, XML-out

Example:

GET: http://localhost/OrderEntry/TestService.wso/SayHello?sName=John
- The method name is passed in as the first trailing path, and parameters are passed in the query string as name/value pairs. - The response data is returned as bare XML (no SOAP envelope) with a content type of text/xml.

This can only be used to pass in simple parameter types.

JSON-In and JSON-Out Support

We now support JSON-in and JSON-out as follows:

POST: JSON-in, JSON-out

Example:

POST: http://localhost/OrderEntry/TestService.wso/SayHello
- The JSON data is passed in with a request content type of application/json. - The method name is passed in the URI's first trailing path. The JSON format is discussed below. - The response data is returned as JSON with a content type of application/json. This will be the same as our current JSON-out format (with changes for faults discussed below).

If the request content type is application/json, the WebApp Server will treat this as a JSON-in/JSON-out post. In such a case, the "JSON" identifier is not required in the URI.

This option will support passing simple and complex types (structs and arrays).

Currently, the web-service test pages do not show JSON-in support. This will be changed by release. Although it is not shown, JSON-in is now supported.

Format for JSON-in Data

The JSON input format is used to represent zero or more input parameters, where a JSON name:value pair will map to a DataFlex parameter. The same WSDL information used for SOAP will be used for JSON (actually, it uses the WebApp's internal WSO format, but that is a technical detail). The number of parameters, their names, and their data types are determined by the WSDL.

  1. The JSON request will be a single JSON object containing the input parameters represented as name/value pairs.

    {
        "Param1": data1,
        "Param..n": data..n
    }
    
  2. The parameter name is determined by the WSDL, which is determined by the DataFlex parameter name in the server-side method. This name is used for validation purposes.

  3. The parameter name:value pair is optional. If missing, an empty value is assumed.

  4. The parameter name:value pair can appear in any order within the JSON object.

  5. If there are no parameters, the entire request may be empty or just contain an empty JSON object.

  6. The value will be a simple data type, an object type (structs), or an array. The required data type is determined by the WSDL.

  7. Structs are represented as JSON objects. Struct member names must match the member name as defined in the WSDL. Struct member names are optional and may appear in any order within the JSON object. If missing, an empty value is assumed.

  8. The format for values follows the standard JSON rules that we are currently using with JSON-out. Dates must be formatted as strings using the XML XSD date and datetime format of "yyyy-mm-dd" and "yyyy-mm-ddThh:mm:ss.fff".

  9. Parameter values and struct members that are uninitialized may be passed as the JSON null type.

  10. Data type limitations: XmlHandle may not be used as a data type in a JSON call. ByRef parameters may not be used with a JSON call. Since you control the definition of the DataFlex Web Service call, these should not represent real limitations.

Some JSON-In Examples:

  1. Single string parameter sName

    { "sName": "John" }
    
  2. Two numeric parameters number1 and number2

    {
        "number1": 3,
        "number2": 7
    }
    
  3. An integer array parameter named CustIds.

    {
        "CustIds": [2, 4, 6, 8, 10, 12]
    }
    
  4. A struct parameter named NewCustomer, which contains a nested struct

    {
        "NewCustomer": {
            "sFirstName": "first",
            "sMiddleName": "",
            "sLastName": "last",
            "Address": {
                "sCustAddress": "add1",
                "sCity": "city",
                "sState": "state",
                "sZip": "1234"
            },
            "sPhoneNumber": "123-123-3333",
            "sFaxNumber": "333-333-3333",
            "sEmailAddress": "john@here"
        }
    }
    
  5. A struct parameter named NewNames, which contains an array of structs

    {
        "NewNames": [
            {
                "sFirstName": "first1",
                "sLastName": "last1"
            },
            {
                "sFirstName": "first2",
                "sLastName": "last2"
            }
        ]
    }
    
  6. A call with no parameters:

    {}  // or just empty
    

Errors and Faults

We support a mechanism for returning error information similar to the SOAP fault. If a JSON call succeeds, the HTTP response code will be 200. If there is an error, some other code (most likely 500) will be returned, and the JSON response may contain additional error information. This information will be returned as application/json in the form of:

{
    "errorCode": "soap:Server",
    "errorDescription": "error_message"
}

where error_message is a message provided by the WebApp Server or from within the DataFlex cWebService method when invoked via the WebServiceException message.

This represents a change from the current WebApp Server where JSON-response errors returned an error as text/html, which is not particularly useful when working with a JSON client.

Formatting of JSON-out

As of 17.1, JSON-out data is stripped of all whitespace. Previously, we added formatting whitespace to make the JSON data easier to read. Removing the space makes the data transferred smaller.

Conclusion

When using the WebApp framework, the use of web services and its exchange format (XML or JSON) is private, low-level, and is not something you will need to use or understand. This information is provided for developers who wish to work at a lower level and perhaps even build their own AJAX-style framework. If you wish to see how WebApp uses web services to exchange information, you can look at the cWebServiceDispatcher class in pkg\cWebServiceDispatcher.pkg. This is a private class that could be used as a template for your own extensions. This is advanced-level usage, and it is expected that you will learn best by studying the code.

Again, it must be stressed that this is not something that most web developers will need to know.

See Also