REST
Naming Convention
All REST universal modules should have the following module label and description:
Module label: Make an API Call
Module description: Performs an arbitrary authorized API call.

URL parameter
Expected input from users should start with / (for example /tasks) so users can copy-paste the endpoint path from the service documentation.
If the API has multiple versions of API available, the user should be allowed to use any of them. The URL set in the universal module should end before the version.
Set the correct URL in help and add a working endpoint example.
Communication
{
"url": "https://www.example.com/{{parameters.url}}"
}Mappable parameters
{
"name": "url",
"type": "text",
"label": "URL",
"help": "Enter a path relative to `https://www.example.com`. For example: `/v1/something`",
"required": true
}Communication
{
"url": "https://www.example.com/v1/{{parameters.url}}"
}Mappable parameters
{
"name": "url",
"type": "text",
"label": "URL",
"help": "Enter a path relative to `https://www.example.com/v1/`. For example: `something`",
"required": true
}The "url" in the Communication has the API version in it.
The help has a misleading example, as the base URL should end without a slash and version, and the example should start with a slash and version.
Rest universal module example

{
"qs": {
"{{...}}": "{{toCollection(parameters.qs, 'key', 'value')}}"
},
"url": "https://www.example.com/{{parameters.url}}",
"body": "{{parameters.body}}",
"type": "text",
"method": "{{parameters.method}}",
"headers": {
"{{...}}": "{{toCollection(parameters.headers, 'key', 'value')}}"
},
"response": {
"output": {
"body": "{{body}}",
"headers": "{{headers}}",
"statusCode": "{{statusCode}}"
}
}
}[][
{
"help": "Enter a path relative to `https://www.example.com`.\nFor example: `/v1/api/list`",
"name": "url",
"type": "text",
"label": "URL",
"required": true
},
{
"name": "method",
"type": "select",
"label": "Method",
"default": "GET",
"options": [
{
"label": "GET",
"value": "GET"
},
{
"label": "POST",
"value": "POST"
},
{
"label": "PUT",
"value": "PUT"
},
{
"label": "PATCH",
"value": "PATCH"
},
{
"label": "DELETE",
"value": "DELETE"
}
],
"required": true
},
{
"help": "You don't have to add authorization headers; we already did that for you.",
"name": "headers",
"spec": [
{
"name": "key",
"type": "text",
"label": "Key"
},
{
"name": "value",
"type": "text",
"label": "Value"
}
],
"type": "array",
"label": "Headers",
"default": [
{
"key": "Content-Type",
"value": "application/json"
}
]
},
{
"name": "qs",
"spec": [
{
"name": "key",
"type": "text",
"label": "Key"
},
{
"name": "value",
"type": "text",
"label": "Value"
}
],
"type": "array",
"label": "Query String"
},
{
"name": "body",
"type": "any",
"label": "Body"
}
][
{
"name": "body",
"type": "any",
"label": "Body"
},
{
"name": "headers",
"type": "collection",
"label": "Headers"
},
{
"name": "statusCode",
"type": "number",
"label": "Status code"
}
]{}OAuth scopes
When your app requires specifying scopes to access different groups of endpoints, you need to change the connection code to ensure that it works correctly with the universal module:
Add a new advanced parameter called scopes to the connection parameters.

[
{
"name": "clientId",
"type": "text",
"label": "Client ID",
"advanced": true
},
{
"name": "clientSecret",
"type": "text",
"label": "Client Secret",
"advanced": true
},
{
"name": "scopes",
"label": "Additional Scopes",
"type": "array",
"help": "Use this to get an access to extra scopes.",
"advanced": true
}
]In the authorize part of the connection, merge the original scopes with additional scopes added by the parameter from the previous step.

"authorize": {
"qs": {
"scope": "{{join(distinct(merge(oauth.scope, ifempty(parameters.scopes, emptyarray))), ',')}}",
"client_id": "{{common.clientId}}",
"redirect_uri": "{{oauth.redirectUri}}",
"response_type": "code"
},
"url": "...",
"response": {
"temp": {
"code": "{{query.code}}"
}
}
}Now a user can add additional scopes manually when creating a connection and these scopes will work with the universal module.
Last updated

