diff --git a/nodes/api/api.html b/nodes/api/api.html
index e63db90b59..ccf6d3914d 100644
--- a/nodes/api/api.html
+++ b/nodes/api/api.html
@@ -38,39 +38,7 @@
$("#node-input-data")
.typedInput({
- types: [
- {
- value: "json",
- label: "JSON",
- icon: "red/images/typedInput/json.png",
- validate: function(v) {
- if (!v) return true;
- try {
- JSON.parse(v);
- return true;
- } catch (e) {
- return false;
- }
- },
- expand: function() {
- const that = this;
- const value = this.value();
- try {
- value = JSON.stringify(JSON.parse(value), null, 4);
- } catch (err) {}
- RED.editor.editJSON({
- value: value,
- complete: function(v) {
- const value = v;
- try {
- value = JSON.stringify(JSON.parse(v));
- } catch (err) {}
- that.value(value);
- }
- });
- }
- }
- ]
+ types: ["json"]
})
.typedInput("width", "68%");
@@ -168,12 +136,39 @@
Configuration
JSON Object to send for WebSocket requests and HTTP posts.
Resultsstring
- Location to saved the API results.
+ Location to save the API results.
+
+
+ Inputs
+
+ - payload.protocol[websocket|http] string
+ - Overrides or sets the protocol property of the config.
+
+ - payload.method[get|post] string
+ - Overrides or sets the method property of the config.
- - Templates
- - Templates can be used in path, params and data fields.
+ - payload.pathstring
+ - Overrides or sets the path property of the config.
+
+ - payload.dataJSON | string
+ - Overrides or sets the data/params property of the config.
+
+ - payload.locationstring
+ - Overrides or sets the results property of the config.
+
+ - payload.locationType[msg|flow|global] string
+ - Overrides or sets the results type property of the config.
Outputs
- Will output the results received from the API call to the location defined in the config.
+ Will output the results received from the API call to the location defined in the config.
+
+ Templates
+ Templates can be used in path, params and data fields. When using templates the top level is a property of the message object: msg.payload
would be {{payload}}
.
+
+ References
+
+ http api
+ websocket api
+
diff --git a/nodes/api/api.js b/nodes/api/api.js
index 3e3b27e06b..01e170c01d 100644
--- a/nodes/api/api.js
+++ b/nodes/api/api.js
@@ -1,5 +1,6 @@
const RenderTemplate = require('../../lib/mustache-context');
const BaseNode = require('../../lib/base-node');
+const Joi = require('joi');
module.exports = function(RED) {
const nodeOptions = {
@@ -12,6 +13,52 @@ module.exports = function(RED) {
data: {},
location: {},
locationType: {}
+ },
+ input: {
+ protocol: {
+ messageProp: 'payload.protocol',
+ configProp: 'protocol',
+ validation: {
+ haltOnFail: true,
+ schema: Joi.string().valid('websocket', 'http')
+ }
+ },
+ method: {
+ messageProp: 'payload.method',
+ configProp: 'method',
+ validation: {
+ haltOnFail: true,
+ schema: Joi.string().valid('get', 'post')
+ }
+ },
+ path: {
+ messageProp: 'payload.path',
+ configProp: 'path',
+ validation: {
+ haltOnFail: true,
+ schema: Joi.string()
+ }
+ },
+ data: {
+ messageProp: 'payload.data',
+ configProp: 'data'
+ },
+ location: {
+ messageProp: 'payload.location',
+ configProp: 'location',
+ validation: {
+ haltOnFail: true,
+ schema: Joi.string()
+ }
+ },
+ locationType: {
+ messageProp: 'payload.locationType',
+ configProp: 'locationType',
+ validation: {
+ haltOnFail: true,
+ schema: Joi.string().valid('msg', 'flow', 'global')
+ }
+ }
}
};
class ApiNode extends BaseNode {
@@ -19,21 +66,24 @@ module.exports = function(RED) {
super(nodeDefinition, RED, nodeOptions);
}
- onInput({ message }) {
+ onInput({ message, parsedMessage }) {
const node = this;
const config = node.nodeConfig;
const serverName = node.utils.toCamelCase(config.server.name);
const data = RenderTemplate(
- config.data,
+ typeof parsedMessage.data.value === 'object'
+ ? JSON.stringify(parsedMessage.data.value)
+ : parsedMessage.data.value,
message,
node.node.context(),
serverName
);
+ const method = parsedMessage.method.value;
let apiCall;
- if (config.protocol === 'http') {
+ if (parsedMessage.protocol.value === 'http') {
const path = RenderTemplate(
- config.path,
+ parsedMessage.path.value,
message,
node.node.context(),
serverName
@@ -45,13 +95,13 @@ module.exports = function(RED) {
return;
}
- if (!['get', 'post'].includes(config.method)) {
+ if (!['get', 'post'].includes(method)) {
node.error('HTTP request requires a valid method');
node.setStatusFailed();
return;
}
- apiCall = config.server.http[`_${config.method}`].bind(
+ apiCall = config.server.http[`_${method}`].bind(
config.server.http,
path,
data
@@ -83,18 +133,21 @@ module.exports = function(RED) {
return apiCall()
.then(results => {
- node.setStatusSuccess(`${config.protocol} called`);
+ node.setStatusSuccess(
+ `${parsedMessage.protocol.value} called`
+ );
const contextKey = RED.util.parseContextStore(
- config.location
+ parsedMessage.location.value
);
contextKey.key = contextKey.key || 'payload';
- const locationType = config.location_type || 'msg';
+ const locationType =
+ parsedMessage.locationType.value || 'msg';
if (locationType === 'flow' || locationType === 'global') {
node.node
.context()
- [locationType].set(
+ [parsedMessage.locationType.value].set(
contextKey.key,
results,
contextKey.store