Throughout the adoption of VXML, using a middle tier provided benefits. The VXML spec doesn’t provide a dynamic DOM, so it is common to have server-side sessions generate VXML documents. This provides benefits like:
- dynamic setting of <property> elements
- prompt management
- state management
- flexible navigation from one vxml document to the next (e.g. MVC )
- calling web services, since VXML only performs GET and form POST, there is no POST for XML or JSON
In 2004, the <data> element was added to VXML in the VoiceXML 2.1 Working Draft. It’s a nice addition, and it buys a little more flexibility with modern web programming’s use of RESTful web services. With REST:
- GET and a variety of POSTs are supported
- The results can be JSON, XML, or other formats. Perfect for VXML scripting
- The resulting XML (or JSON) is much cleaner and less overhead, than implementing SOAP
This means you have native (but limited) VXML access to REST web services!!! However, the <data> element in VXML is treated similarly to a <var> element, even though it has more in common with a <subdialog> element. For example, the <var> element can be assigned a value, and will throw error.semantic if it has issues, while the <data> element is fetching resources and can throw error.badfetch. To make things worse, the <data> element does not allow <catch> child elements.
As a result, you have to invert logic. Here’s a simple formula to accomplish that:
- for variables passed to the REST functions, and the result sets, define the variables at a document or application scope, so they may be shared across your consecutive REST calls. If you are making only one call, you can define them at the same level as the data element.
- create a form for each <data> call:
- put the <data> element in a <block>
- at the form level, define the <catch> elements for the HTTP response codes, other than 200, the REST implementation will throw, and handle the response codes appropriately. This goes above the <data> element mentioned above, but logically thinking, it comes second.
- In another block under the <data> block, handle the 200(OK) http response. Don’t do it in the same block as the data call. Based on my experience, it is prudent to handle it in a following block.
I’ve used this technique to implement Voice Verification services from Voice Biometrics Group.
You can see/run the sample code here, or you can clone my repo:
git clone https://bitbucket.org/ericp56/ericp56.bitbucket.org