-
Notifications
You must be signed in to change notification settings - Fork 14
In Form HTTP Requests
NOTE: This is a preliminary spec in-planning and shouldn't be considered live in any version of the platform.
A form can support a very limited capacity to perform a live HTTP request for a value and inject that response into the form. This spec/example will demonstrate what components are associated with the request and how they work.
This support is structured as a partial implementation of the XForms 1.1 spec, and the implemented elements match that specification.
This spec defines the expectation of how platforms which support HTTP requests will function. On platforms where no HTTP request support is available, the expectation will be that <send>
actions are simply no-ops, which matches the current output on a supported system where the request fails.
The only compatible endpoint and response format currently supported is an HTTP GET request which returns a raw text response. For our example, we will assume that the endpoint is defined as
https://example.com/request
and that the response is the flat value
server_response
CommCare will provide whatever authentication is requested using the credentials of the currently logged in user.
The HTTP timeout is unspecified by the XForm specification, and will rely on the default timeout used by the platform.
The response must contain a valid XML text value which can be set as the value of the target ref. If the response contains text which would be invalid as the body of an XML text value (like an un-escaped <
), it will be treated as an error in the outcomes below.
A 200 response containing a valid string will result in the request completing its lifecycle and setting the value in the form.
Any other response, error, or other outcome will result in the triggering event completing with no other side effects (no values set, no additional events produced). This means that forms must be capable of functioning without input from the request/response layer.
The request can support providing HTTP URL Parameters. In order to do so, the parameters (name/value) must be provided as child elements of an instance element in the form.
Example:
<data>
<question_1/>
<landing_for_response/>
<request_params>
<param1>value1</param1>
<param2>value2</param2>
</request_params>
</data>
When /data/request_params
is used as the reference for the request, the url string requested will be
https://example.com/request?param1=value1¶m2=value2
The structure of the request will need to be encoded in the XForm's <model>
as a <submission>
element. This element does not encode a specific action, but rather provides a template of an action which will be performed on request.
Only the following submission structure is currently supported (dynamic parameters are defined with empty bodies)
<submission id="" resource="" ref="" targetref="" method="get" replace="text" mode="synchronous" />
The following parameters are required to be defined per request template
-
id
- A string defining an ID which will be used to reference this request in the form -
resource
- The URL of the request endpoint. Only HTTP/HTTPS web requests are supported -
targetref
- An XPath reference to an element in the form whose current value will be replaced with the response text. This element must exist and must be a "leaf" node (have no children)
The following parameters may be defined per request template
-
ref
- An XPath Reference to a "parent" element in the form whose children will be used as key/value pairs to provide URL parameters for the request.
For our example, the submission definition will be:
<submission id="http_request_id" method="get" resource="https://example.com/request" ref="/data/request_params" replace="text" targetref="/data/landing_for_response" mode="synchronous" />
The <submission>
template is not an action in the form, and thus one must be provided to trigger the HTTP request.
The <send>
action will signal the form to perform the actual HTTP request for a submission template definition. As an action it should be inserted into the model (similar to <setvalue>
events).
It's definition is
<send event="" submission=""/>
Where the following are required to be defined
-
submission
- A string referencing an ID which is defined by a<submission>
to be used -
event
- The event that should trigger this request
Example:
<send event="xforms-ready" submission="http_request_id"/>
<html>
<model>
<instance>
<data>
<question_1/>
<landing_for_response/>
<request_params>
<param1>value1</param1>
<param2>value2</param2>
</request_params>
</data>
</instance>
<submission id="http_request_id" method="get" resource="https://example.com/request" ref="/data/request_params" replace="text" targetref="/data/landing_for_response" mode="synchronous" />
<send event="xforms-ready" submission="http_request_id"/>
</model>
<body>
<input ref="question_1">
<label>The server responded with <output value="/data/landing_for_response"/></label>
</input>
</body>
</html>
- Form Opened. Form initialization starts
- Event:
xforms-ready
fired for form - Action:
send
triggered by event-
send
action retrieves<submission>
template based on IDhttp_request_id
-
/data/request_params
looked up, child nodes evaluated - HTTP Request opened for:
https://example.com/request?param1=value1¶m2=value2
- 200 Response returned
- Response Body parsed, result text
server_response
is read a the response - The targetref element
/data/landing_for_response
is identified in the form -
<landing_for_response>
element is populated with the value:<landing_for_response>server_response</landing_for_response>
-
- Form Initialized
- First question displayed with prompt "The server responded with server_response"
- Form Opened. Form initialization starts
- Event:
xforms-ready
fired for form - Action:
send
triggered by event-
send
action retrieves<submission>
template based on IDhttp_request_id
-
/data/request_params
looked up, child nodes evaluated - HTTP Request opened for:
https://example.com/request?param1=value1¶m2=value2
- Request times out
-
send
action is aborted. No form values are changed
-
- Form Initialized
- First question displayed with prompt "The server responded with "