HomeGuidesRecipesAPI
HomeGuidesAPILog In

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.

Action Configuration

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 NameDescriptionRequired?
URLThe endpoint of the serviceYes
HTTP MethodThe 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/PasswordThe 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 HeadersAny 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 ValuesRequest data to be sent as Name - Value pairs.No
Send Access TokenTrue/false representing whether to send the user's OpenIdConnect access_token as a Bearer token for the request if one exists.No
Send as MultipartWhether to construct a multi-part request (for example, if the body document will exceed the service's maximum request length).No
Output PathA parameter that defines a path in the REST response that will be output as the Output Path Data parameterNo
Request BodyJSON 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 SchemaRequests 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 use JsonEncode() 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.

1067

Selecting a body document for the REST request

📘

Document types

The Action will automatically detect the document extension (JSON or XML) configure the request headers appropriately (application/json or application/xml).

🚧

Number of Document

Only a single JSON or XML 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:

  1. 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

  2. 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

  1. Create a new project in Design
  2. Import the example.schema.json document as a project template
  3. Create some Text Input questions and map their Answers to the template placeholders
  4. Add a "Send to REST Service" action to the project's Finish page
  5. Supply parameters for the action as follows:
  1. 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.
  2. 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
  3. For Delete of the resource created in Step 5 supply following parameters to the action with no action document

Troubleshooting Modes

To troubleshoot the problems in Send to REST Service action, make sure to check Troubleshooting Mode in the project Publish Options.

767

Send to REST Service Action Troubleshooting

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"
  },

Related Content

Take a look at the REST Data Source type, to retrieve data posted in a previous form session.