Send to REST Service Action
SmartIQ includes the ability to send form data to a REST service, via the "Send to REST Service" action.
The action provides three outputs. These outputs can be referenced and used conditionally:
- Status (the HTTP response such as "OK", "CREATED")
- Response (the HTTP response body, if any)
- Output Path Data (the results, as a value or snippet, of the Output Path against the Response)
Note:
The success of the Send to Rest Service action reflects whether the action was able to communicate with the REST endpoint. The action will return a success as its own status even if it gets an error from the service. If action needs to be taken based on an error from the REST service use the Status output of the action.
The Send to REST Service action can be added to a project in Design, either on the Finish page or as part of a Workflow transition.
The input parameters for the action are as follows:
Input Name | Description | Required? |
---|---|---|
URL | The endpoint of the service | Yes |
HTTP Method | The HTTP method to use for the request. Supported values are "GET ", "POST ", "PUT ", "DELETE " and "PATCH ". Defaults to "POST " if not specified. | No |
Basic Auth Username/Password | The username and password to supply for HTTP Basic Auth or Windows Auth, if required by the service. Note: For HTTP services, these inputs can only be used for services that correctly return a challenge response (401). For all other HTTP services use custom headers. | No |
OAuth 2.0 Client Id * | Unique Id that represents this application, obtained from the IDP. | No |
OAuth Client Secret * | Shared secret to prove that the request comes from the right application. | No |
OAuth 2.0 Scope * | The available scopes for the OAuth2 security scheme. | No |
OAuth 2.0 Token URL * | The token URL to use for this flow. | No |
OAuth 2.0 Username/Password * | The resource owner username and password. | No |
Custom Headers | Any custom headers (such as an authorisation token or other special data) to supply as part of the request. Multiple headers can be specified if necessary. | No |
Form Values | Request data to be sent as Name - Value pairs. | No |
Send Access Token | True/false representing whether to send the user's OpenIdConnect access_token as a Bearer token for the request if one exists. | No |
Send as Multipart | Whether to construct a multi-part request (for example, if the body document will exceed the service's maximum request length). | No |
Output Path | A parameter that defines a path in the REST response that will be output as the Output Path Data parameter | No |
Request Body | JSON or XML request to be included in the REST request. JSON can have a question reference used with formula JsonEncode() or HtmlEncode() to sanitize user entered values. If action also includes a Document, it will be ignored and Action Input. When implemented, Action ignores Send as Multipart. | Yes, if no document is specified with the Action. |
Request Schema | Requests the metadata for how the data will be structured and prevents unintentional JSON or XML elements being included in a REST request due to injection from user input or specific parameters in the request. If Request Body action input is implemented, "Request Schema" needs to be supplied, validating the Body against the JSON Schema or XSD (XML Schema Definition) provided in this Action Input prior to sending the request. - If a Request Schema is not supplied, an error is thrown describing the rationale for requiring it. - If the Request Body action input is JSON, the Request Schema needs to be a JSON Schema. If the Request Body action input is XML, the Request Schema needs to be XSD. - If the Body fails validation against the Schema, an error is thrown describing which element(s) were incorrectly included/excluded. - Notably, if the provided Schema specifies that additional elements can be included, this is overridden. The supplied Schema needs to be an exact specification of which elements are to be allowed. | Yes, if Request Body is included. |
OAuth 2.0 Note
The built in OAuth 2.0 inputs make a standard access token request that passes the client id and client secret as Basic Authentication headers, with a grant type of
client_credentials
.Where a service requires a different access token request format, such as requiring additional fields or inputs as form fields in the request, do not the OAuth 2.0 inputs, instead build an appropriate two part request with the access token passed between the first and second call.
All OAuth 2.0 requests (whether using the standard inputs or a custom call) require a client credential server/server flow and cannot be implemented using a server/user flow.
For full details of what is supported by SmartIQ see here
Important
Is not required to provide a JSON Template to use this Action. Simply use the Body Request Action Input and provide a JSON Schema using Request Schema.
It is recommended to useJsonEncode()
Formula to encode User inputs (Do not encode the whole JSON payload as it will result in a runtime error.
For example:
- Formula to encode user input:
JsonEncode([q1])
- Formula to generate JSON to be used in Body Request Action Input:
=Concat("{""text"":""",[q2.3],"""}")
resolves to:{"text":"Encoded text \"here\""}
for example.
Including Body Request
Request Body using a Document
The action accepts an optional body document to be sent as the content of the request, this should be included as an SmartIQ template within the project, mapping placeholders to the appropriate questions and attached as an Action Document.
Document types
The Action will automatically detect the document extension (
JSON
orXML
) configure the request headers appropriately (application/json
orapplication/xml
).
Number of Document
Only a single
JSON
orXML
body document can be provided. If more than one is supplied, either explicitly through "Custom" action document settings, or implicitly through multiple templates being present in the project and not deactivated by conditions, the REST Service action will throw an error.
Request Body using a String
Alternatively, designers can provide the body request as a String using the Action Input Request Body in combination with Request Schema, note that this feature is only available for JSON payloads. This feature provides more flexibility on when the action will run as there's no need to generate a document.
The ability to include a schema within the request allows designers to:
- Restrict the number of parameters used in the request.
- Ensures that the request is in accordance with the schema.
- Prevent unintentional JSON or XML elements elements from being included.
SECURITY CONSIDERATION
Use the JsonEncode() formula when adding JSON user inputs or HtmlEncode() to prevent ambiguous characters to be fixed as well as prevent malicious inputs. However, if you are using the xsd template to generate your xml body, you do not need to worry about special character encoding.
Let's pretend we have a REST API that allows to create new customers in a cloud CRM, that accepts the following JSON
request:
Body Request Examples
{
"firstname":"John",
"lastname":"Doe",
"address":"123 Address St, Anywhere",
"phone": "(01) 2345 6789",
"loginDetails":{
"username":"usernameHere",
"password":"passwordHere"
}
}
<?xml version="1.0" encoding="UTF-8"?>
<Pet>
<id>0</id>
<Category>
<id>0</id>
<name>Dog</name>
</Category>
<name>doggie</name>
<photoUrls>
<photoUrl>http://somedogurl.com</photoUrl>
</photoUrls>
<tags>
<Tag>
<id>0</id>
<name>doggie tag</name>
</Tag>
</tags>
<status>available</status>
</Pet>
Schema Examples
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"firstname": {
"type": "string"
},
"lastname": {
"type": "string"
},
"address": {
"type": "string"
},
"phone": {
"type": "string"
},
"loginDetails": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"password": {
"type": "string"
}
},
"required": [
"username",
"password"
]
}
},
"required": [
"firstname",
"lastname",
"address",
"phone",
"loginDetails"
]
}
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Pet">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:byte" name="id"/>
<xs:element name="Category">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:byte" name="id"/>
<xs:element type="xs:string" name="name"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element type="xs:string" name="name"/>
<xs:element name="photoUrls">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="photoUrl"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="tags">
<xs:complexType>
<xs:sequence>
<xs:element name="Tag">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:byte" name="id"/>
<xs:element type="xs:string" name="name"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element type="xs:string" name="status"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
As described earlier, user inputs should be properly encoded, for example, if a user provides SmartIQ "Australia" for the name, the formula will properly encode the character "
.
Similarly, if the user provides SmartIQ "loginDetails":{"username":"usernameHere","password":"passwordHere"} as the Name, the full string will be included as the actual name string by using JsonEncode or Htmlencode instead of including the string as part of the request.
In the same vein, the usage of the schema in combination with JsonEncode() formula allows restricting the usage of specific parameters just by removing them in the schema.
Attachments
If an attachment is to be included with the rest service, you can use two methods:
-
If your request body uses a JSON document then add the appropriate JSON placeholder onto the attachment answer - this will insert the uploaded/generated document into the JSON as base 64
-
Alternatively attach the document to the REST action and set the "Send as multipart" input
Send As Multipart behaviour
When "Send As Multipart" is set to true, the request will be sent as a standard request of type "multipart/form-data".
This will result in a single request, with the body of the request being a set of files separated by a randomized delimiter string. Handling such a request appropriately is up to the receiving service.
Body documents for Multipart requests
If a Request Body is supplied by the action inputs it will override the document-based inputs entirely and will prevent any documents from being attached. This input should not be supplied for a multi-part request.
Additionally, if a body document (e.g. JSON or XML) is included, when "send as multi-part" is used that document will be included along with any other documents and not sent separately. Generally for this type of request, non-document information will be supplied on the request path or the query string.
Custom headers
Custom headers, if required by the service, can be supplied using the Custom Header action parameter. Zero or more headers may be specified as a key-value pair, and will be sent as part of the REST request.
Using Form Value data
As an alternative to sending data in the body of a request, you can send key-value pairs as Form Values. These key-value pairs can be added using the Form Values action input. Add a new input record for each key-value pair.
- Form Values are only sent if the request body is empty. When form values are supplied and the request body is empty, the Content Type will default to
x-www-form-urlencoded
. - The multipart/form-data Content Type can be used to send Form Values and documents together in the same request. This can be specified using the
Send as Multipart
input property. - The Content Type can also be set with Custom Headers. This will take precedence over the
Send as Multipart
setting and defaults.
Using the Status and Response outputs
The Status and Response outputs can be referenced by subsequent Actions, for example to drive the display of a message to the user, or to store the response body in a database for later reference.
Using an Output Path and the Output Path Data
A path to a value or node in the Response to the REST call can be specified using the Output Path parameter.
Possible path formats are JSONPath for JSON responses or XPath for XML responses
JSONPath
JSONPath expressions always refer to a JSON structure in the same way as XPath expression are used in combination with an XML document. Since a JSON structure is usually anonymous and doesn't necessarily have a "root member object" JSONPath assumes the abstract name $ assigned to the outer level object.
JSONPath expressions in SmartIQ use the dot–notation (JSONPath uses a 0 based index):
$.store.book[0].title
An example Output Path Data value in this case might be "The Da Vinci Code"
or if the Response only returns a single node you can leave out the index.
$.store.book.title
If you use a non indexed call (like the one just above) against an array or a response with many nodes you will get all the relevant title values as a | separated string
An example Output Path Data value in this case might be "The Da Vinci Code|The Lord of the Rings|Anne Frank Diary of a Young Girl"
If you call a path that is an node rather than a value, you will get a JSON snippet in return.
For example an Output Path of:
$.address
Might result in a JSON snippet like this as the Output Path Data value, because the path does not have a simple value.
{ "street": "Kulas Light", "suite": "Apt. 556", "city": "Gwenborough", "zipcode": "92998-3874", "geo": { "lat": "-37.3159", "lng": "81.1496" } }
XPath
XPath uses a 1 based index.
/bookstore/book[1]
An example Output Path Data value in this case might be "The Da Vinci Code"
or if the Response only returns a single node you can leave out the index.
/bookstore/book
If you use a non indexed call (like the one just above) against an array or a response with many nodes you will get all the relevant title values as a | separated string
An example Output Path Data value in this case might be "The Da Vinci Code|The Lord of the Rings|Anne Frank Diary of a Young Girl"
If you call a path that is an node rather than a value, you will get an XML snippet in return.
For example an Output Path of:
/CUSTOMER
Might result in an XML snippet like this as the Output Path Data value, because the path does not have a simple value.
<ID>18</ID><FIRSTNAME>Sylvia</FIRSTNAME><LASTNAME>Fuller</LASTNAME><STREET>158 - 20th Ave.</STREET><CITY>Paris</CITY>
Retrieving header values
The value of a HTTP header in the received response can be set as an output by specifying an output path in the form:
header=HeaderName
If the specified header is present in the response, its value will be returned as the action output. If the header is not present, the output will be blank.
Sample project
The following section will walk through constructing a project to send some REST data to the https://jsonplaceholder.typicode.com/ test service.
Sample JSON schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {},
"id": "http://example.com/example.json",
"properties": {
"body": {
"description": "An explanation about the purpose of this instance.",
"id": "/properties/body",
"type": "string"
},
"title": {
"description": "An explanation about the purpose of this instance.",
"id": "/properties/title",
"type": "string"
},
"userId": {
"description": "An explanation about the purpose of this instance.",
"id": "/properties/userId",
"type": "integer"
}
},
"type": "object"
}
Project setup
- Create a new project in Design
- Import the
example.schema.json
document as a project template - Create some Text Input questions and map their Answers to the template placeholders
- Add a "Send to REST Service" action to the project's Finish page
- Supply parameters for the action as follows:
- URL: https://jsonplaceholder.typicode.com/posts
- HTTP Method: POST
- Optionally, add an Output Path value of
$[4].title
to get an Output Path Data value which should match the title of the 5th post in the Response. - Optionally, set up the Action Documents to pass only the correct document to the Action. If there are no other JSON or XML templates in the project this step is unnecessary, as the default "All" setting will work fine
- For Delete of the resource created in Step 5 supply following parameters to the action with no action document
- URL: https://jsonplaceholder.typicode.com/posts/{UserIdCreated}
- HTTP Method: DELETE
Troubleshooting Modes
To troubleshoot the problems in Send to REST Service action, make sure to check Troubleshooting Mode in the project Publish Options.
To log more detailed troubleshooting data including all REST parameters and values, check Show Variables and Show Invisible Datasources. Also in AppSettings.json file under produce, make sure to add "ShowDatasourceTroubleshootingErrors": "True" under AppSettings.
"AppSettings": {
"ShowDatasourceTroubleshootingErrors": "True"
},
Updated almost 2 years ago
Take a look at the REST Data Source type, to retrieve data posted in a previous form session.