Introduction
More and more services are exposed and consumed through REST APIs, in other words APIs that leverage
HTTP. In particular, the XForms <xforms:submission> supports
REST as of XForms 1.1. The XForms Submission processor exposes the functionality of
<xforms:submission> to XML pipelines and allows you to call REST services from XPL
without creating XForms pages.
Inputs and outputs
| Type |
Name |
Purpose |
Mandatory |
| Input |
submission
|
Configures the XForms submission |
Yes |
| Input |
request
|
Refers to the document to submit |
Yes |
| Output |
response
|
Produces the result document if any |
Yes |
The XForms Submission processor is typically called this way from XPL pipelines:
<p:processor name="oxf:xforms-submission">
<p:input name="submission">
<xforms:submission method="put"
action="/exist/rest/db/ops/dmv-example/resources.xml"/>
</p:input>
<p:input name="request" href="#document"/>
<p:output name="response" id="response"/>
</p:processor>
Processing model
The submission input follows the semantic of <xforms:submission>, with the
difference that the replace attribute defaults to the value instance.
Processing follows the following steps:
-
The document provided on the request input is set as the default XForms
instance.
-
The submission is executed. By default, the submission serializes the default instance, that is
the document provided on the request input.
-
The resulting default instance is produced on the response output. In case of
sucessful instance replacement, this means that the document resulting from the submission is
produced.
If an XForms submission error occurs during the processing of the submission, the response document will
be identical to the request document unless you modify it using XForms events and actions.
You have to consume the response output in order for the submission to be performed, even
if you do not wish to handle the response document.
NOTE: This processor doesn't allow for streaming of input and output documents: those will be converted into DOM internally. This means it is not always adequate for very large input or output documents.
GET example
This is how you perform a GET of an XML document to the URL http://example.org/list?first=12&size=100:
<p:processor name="oxf:xforms-submission">
<p:input name="submission">
<xforms:submission method="get"
action="http://example.org/list"/>
</p:input>
<p:input name="request">
<parameters>
<first>12</first>
<size>100</size>
</parameters>
</p:input>
<p:output name="response" id="response"/>
</p:processor>
POST example
This is how you perform a POST of an XML document to the URL
http://example.org/rest/my-collection and retrieve an XML response:
<p:processor name="oxf:xforms-submission">
<p:input name="submission">
<xforms:submission method="post" action="http://example.org/rest/my-collection"/>
</p:input>
<p:input name="request" href="#request"/>
<p:output name="response" id="response"/>
</p:processor>
PUT example
This is how you perform a PUT of an XML document to the URL
http://example.org/rest/my-collection/my-document and retrieve an XML response:
<p:processor name="oxf:xforms-submission">
<p:input name="submission">
<xforms:submission method="put"
action="http://example.org/rest/my-collection/my-document"/>
</p:input>
<p:input name="request" href="#request"/>
<p:output name="response" id="response"/>
</p:processor>
DELETE example
This is how you perform a DELETE of a resource located at
http://example.org/rest/my-collection/my-resource:
<p:processor name="oxf:xforms-submission">
<p:input name="submission">
<xforms:submission method="delete"
action="http://example.org/rest/my-collection/my-resource"/>
</p:input>
<p:input name="request"><dummy/></p:input>
<p:output name="response" id="response"/>
</p:processor>
<p:processor name="oxf:null-serializer">
<p:input name="data" href="#response"/>
</p:processor>
In this case the response is read but discarded by using the Null Serializer.
Handling errors
You can handle errors using XML events and actions, including xforms-submit-error and
xforms:setvalue.
<p:processor name="oxf:xforms-submission">
<p:input name="submission">
<xforms:submission method="put"
action="http://example.org/rest/my-collection/my-resource">
<xforms:setvalue ev:event="xforms-submit-error" ref="submission-error"
value="'true'"/>
</xforms:submission>
</p:input>
<p:input name="request" href="#request"/>
<p:output name="response" id="response"/>
</p:processor>
The above example assumes that the request document contains a <submission-error>
element under its root element, for example:
<request>
<submission-error>false</submission-error>
...
</request>
You can then check that an error occurred by testing that the response document satisfies
/request/submission-error = 'true'.
Handling authentication
You can use Basic HTTP authentication (the most
widely used authentication mechanism over HTTP) in two different ways:
-
With username and password encoded in the URL, for example:
<p:processor name="oxf:xforms-submission">
<p:input name="submission">
<xforms:submission method="get"
action="http://john:password@example.org/list"/>
</p:input>
<p:input name="request" href="#request"/>
<p:output name="response" id="response"/>
</p:processor>
This method has the obvious drawback of making authorization credentials visible on the URL. In
particular, if that URL may show in logs, error messages, etc.
-
With two extension attributes, xxforms:username and xxforms:password:
<p:processor name="oxf:xforms-submission">
<p:input name="submission">
<xforms:submission method="get"
action="http://example.org/list"
xxforms:username="john" xxforms:password="password"/>
</p:input>
<p:input name="request" href="#request"/>
<p:output name="response" id="response"/>
</p:processor>
|
|