United eWay tWSDL: API Proposals
The tWSDL API should take into account the overall proposed structure outlined in the System Overview. Although the System Overview does not show all details, roughly speaking each box, at a minimum, will represent a distinct module, or namespace. An exact list of functions cannot be arrived at at this stage of development, but certain general considerations can be established. The following discussion will trace the steps a developer would take in using the tWSDL API to develop an application.
Development of Types

I am finding it hard to overstress the importance of types in the WSDL framework. This is especially important to understand for Tcl programmers who rarely have to deal with types until some bug shows up and forces the issue. But the same can be said of programmers in general. Many many bugs and corresponding developer time can be traced to feeding the wrong data to a function. A Web Service essentially allows a remote user to invoke functions on a system with data of the user's choice. Even with the best of intentions, it is unwise to accept un-checked data from users.

Fortunately WSDL demands the use of XML Schema to define types. At first, XML Schema appears to be difficult and complicated. In actual fact, it is rather easy to explain and use. In explaining it here, I will introduce the expected API for defining types.

Simple Types (simpleType)
Every developer is familiar with simple types. From now on, I will refer to any XML Schema type that is simple as a simpleType. This will distinguish it from simple types in other languages. A simpleType is Atomic. Atomic means that a simpleType cannot be decomposed any further. All XML Schema built in types are simpleTypes.
XML Schema has an extensive number of 'built-in' types. These built-in types are also called 'primitive' types. The real meaning is that in order to completely support XML Schema the software package must provide these built-in types so that all other simpleTypes can be constructed from them. An example of the API for including primitive types is as follows:

proc ::wsdl::types::newPrimitiveType {typeName code description} {

    namespace eval ::wsdl::tcl::$typeName [list variable description "$description"]

    proc ::wsdl::tcl::${typeName}::validate { value } $code
}
 
 

The top level namespace is ::wsdl. This may change, for instance maybe ::twsdl would be better. Below that is the ::wsdl::tcl namespace. I am temporarily using this namespace as an indication that the type checking are based upon tcl types, and are not yet exactly the same as the definition given by XML Schema. Once we have a complete list of primitive types that match XML Schema types, we can move the primitive namespace to something else. However, it will still be possible to create derived types based upon the Tcl types, they will still be primitive in tWSDL, but will require the client to be the tWSDL client.

It will often be the case that a simpleType will be identical to another type except by name. In this case, we need an API which creates the type and uses the built in validation for the original type:

proc ::wsdl::types::addSimpleType {tns typeName {base "tcl::anySimpleType"} } {

    namespace eval ::wsdl::${tns}::${typeName} [list variable base "$base"]
    
    proc ::wsdl::${tns}::${typeName}::validate { value } "
       variable base
       if {\[::wsdl::\${base}::validate \$value]} { 
           return 1} else { return 0}"

} 
 

This API also demonstrates that types have namespaces. (Note that this is different than a Tcl namespace, although we will use the type namespace name as the name of the Tcl namespace for the type.) The example API puts the type namespace as a child of the ::wsdl namespace. It might be necessary to create a separate toplevel for all types.

New simpleTypes can also be derived from other simpleTypes or primitive types. You derive a new simpleType by several means: one is by enumeration and the other is by pattern.

Here are example calls of both API:


::wsdl::types::restrictionByEnumeration::new "CreditCardTypeCode" "s:string" {

 "Visa"  "Mastercard"  "AmericanExpress"  "Discover"  "DinersClub" 

}

::wsdl::types::restrictionByPattern::new "guid" "s:string" \
 {[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}}