Flexible (Structure of Inputs, Names NOT Individually Defined in the WSDL)
Not all development environments require the use of generated stubs (see section Calling SOAP Methods), but some do. Client problems arose when the SBA needed to add new inputs to various services. For example, the ETran method Originate always returned errors using the XML tag names that failed validation. To allow a client to request error messages in plain English instead of XML tag names, there had to be a new method name Originate2, which defined the additional input. Adding a new method changed the WSDL file. Lenders who used development environments that generate stubs were forced to generate new stubs, recompile, relink, etc. Although a normal part of the Web Services lifecycle, some client developers perceived this adaptation as a setback. And that slowed the rate of development of SBA Web Services.
Fortunately, one of the data types allowed by SOAP is “structure”, which is an arbitrarily large collection of name/value pairs. (This corresponds to a HashMap in Java, a Map in PHP or an object in JavaScript.) Early versions of the SOAP standard allowed structures to contain only string values, which was good enough to allow a new, much more flexible interface for future development called “structure-in/structure-out”.
Structure-in/structure-out design takes only a single structure as its input, moving all a method’s inputs (and even the method name itself) out of the WSDL and into the input structure. This allows the WSDL to stay the same. A single, shared entry point always accepts just the input structure, and that fact never changes. So clients never have to regenerate stubs, recompile, relink, etc. Calling a web service is simply a matter of loading the desired name/value pairs into the structure.
Similarly, by allowing a structure as the output, structure-in/structure-out design allows many values to be returned, as approproiate to context. Again, the WSDL doesn’t change, and there’s no need to regenerate stubs, etc.
Some implementers had development environments that didn’t support structures as inputs, but there was a simple workaround for that. A new serialization format called JSON provided an easy way to define a structure as a string. All seemed to be able to handle output structures just fine, so all that was necessary was to define an equivalent 2nd method that accepts a JSON string that deserializes into a structure, which is done with braces: {"name1":”value1", "name2": "value2"; … } JSON is now an industry standard serialization mechanism, allowing clients to use the SBA’s structure-in/structure-out services even if they don’t have the ability to specify structures directly.
When an SBA Web Service uses this flexible style of coding, its inputs and output will be described in this manner:
SOAP Component | (URL of WSDL file) |
SOAP Method | (Method that expects a structure), only input is structure (input name) |
Or: | (Method that expects a JSON string), only input is JSON string (input name) |
Keys of the Input Structure: | |
(Mandatory/Optional) (Description of its value in the input structure) | |
(Mandatory/Optional). (Description of its value in the input structure) | |
Keys of the Output Structure: | |
(Description of its value in the output structure) | |
(Description of its value in the output structure) | |
The word “key” is often used to mean a name that references a name/value pair in a structure. Seeing the word “Keys” at the starts of the bulleted lists is a deliberately redundant reminder that they’re in the structures, not the WSDL.
To illustrate how to call methods using the flexible interface (structure-in/structure-out), ExtractOrigination makes a good example, because it has only a few inputs. Here’s a Java example of how to call SharedEntryString using call-by-position. (Since there’s only one input, it’s the only one passed, and there’s no need to name it.)
Suppose wsClientObject is a Java object that has been instantiated to call the component whose WSDL is at http://catweb.sba.gov/elend/ws/elend.wsdl If your development environment has no problem specifying a structure as an input parameter, you could call SharedEntryPoint with a structure like this:
HashMap request = new HashMap();
request.put("MethodNamePhysical", "ExtractOrigination");
request.put("CLSUsername", "xxx");
request.put("CLSPassword", "yyy");
request.put("ApplicationNumber", "123456");
request.put("EMail", "zzz@zzz.zzz");
request.put("ExtractOptions", "cmp,env");
request.put("ExtractReason", "save offline");
request.put("FormatOut", "XML");
HashMap response = wsClientObject.SharedEntryPoint(request);
But suppose your development environment doesn’t support calling a SOAP Web Service with a structure. You could instead pass the same structure as a JSON-serialized string like this:
HashMap response = wsClientObject.SharedEntryString
("{"
+"'MethodNamePhysical':'ExtractOrigination',"
+"'CLSUsername':'xxx',"
+"'CLSPassword':'yyy',"
+"'ApplicationNumber':'123456',"
+"'EMail':'zzz@zzz.zzz',"
+"'ExtractOptions':'cmp,env',"
+"'ExtractReason':'save offline',"
+"'FormatOut':'XML'"
+"}");
Regardless of which method is called, the response is a HashMap. It’s very typical of structure-in/structure-out methods to return error messages, whether your password needs to be updated and other response data. If the error messages contain text, it usually means the request failed and the other fields may not be trustworthy.