Processors - XForms Submission


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:

  1. The document provided on the request input is set as the default XForms instance.

  2. The submission is executed. By default, the submission serializes the default instance, that is the document provided on the request input.

  3. 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>
Comments