When you use Node-RED on IBM Cloud during hackathons you will notice REST calls in flows cannot be directly invoked from a web application. The reason for this is mostly that cors (cross-origin resource sharing) is not enabled for the Node-RED server. This blog post is a simple workaround for this problem.
By the way, you can use the IBM Cloud for free, if you simply create an IBM Lite account. Here you only need an e-mail address.
I developed this workaround to have full control and be very flexible during a hackathon, when using Node-RED for prototyping and building integrations to services and web-applications, without changing Node-RED settings or using cors browser enabler.
Existing solutions or workarounds for cors
To handle this problem, there are existing solutions and workarounds out there.
Change the Node-RED settings or add additional functions nodes
Here are three resources I found in the internet.
- How to change settings in Node-RED to allow CORS
- Allowing CORS from a Node-Red Bluemix application
- Enable cors-with-node-red
Note: If you want to change the settings for Node-RED on IBM Cloud, just be aware that these configurations are stored in the related Cloudant database. If you want to see how this is related to the Node-RED Starter application, you can watch my youtube video (5 min): How to setup Node-RED starter on IBM Cloud
Using cors enabler for browsers
As a workaround you can also just search for a cors enabler for browsers. With this workaround you only have to run your web application in the cors enabled browser during the hackathon.
Simple forwarding server
My approach is just developing a simple forwarding server as a workaround. In this server I just forward REST calls from the WebApp to the Node-RED server. The reason for creating this workaround and just not taking one of the existing solutions is: I want to be independent of the Node-RED configuration settings, and I don’t want to use a cors browser enabler.
I just want a easy workaround with a fully controlled extra server. Yes, it needs an additional Node instance, but from my perspective, this is ok.
In the following sequence diagram you can see the REST requests and replies, for the WebApp, Forwarding server, and Node-RED.
The relevant code for the server
To ensure that cors does not cause a problem, I chose to use the cors npm package for the forwarding server. With 1,373,853 downloads a week, this package should be useful ;-).
In this code snippet you can see how I added cors into the server.js file.
var cors = require("cors"); // Cors app.use(cors());
In the following source code of a REST GET you can see: I take the body to forward the data in the request and response of the REST calls. I only modify response status code and the value does not reflect the value I get from the Node-RED server response. In the code I use the response status code 200 for a success and 400 for an error . Feel free to change this.
Note: If you use the sample replace the https://YOUR_NODE_RED_URL/YOUR_REST_CALL with your URL and REST call in the server file.
I expect the json format for the data exchange. So, each REST call of your Node-RED flows should provide json in the payload. All this will make life easier, when you cut and paste the REST call code and only doing a minimum of changes in the simple forwarding server file.
By the way: you can import the sample Node-RED flow I used as a starting point.
Here is the source code of a REST GET in the server.js:
app.get('/getData', function(req, res) { var request=require("request"); var reqURL="https://YOUR_NODE_RED_URL/getData"; console.log("URL: \n", reqURL); var httpHeaderOptions= { accept:"application/json", "content-type":"application/json", }; var restoptions= { method:"GET", url:reqURL, headers:httpHeaderOptions, }; console.log("send request"); request(restoptions, function(error, response, body) { console.log("in request \n"); if (error) { console.error("Failed: %s", error.message); body= {"error":error.message }; res.status(400).json(body); } else { console.log("Success: \n", body); res.status(200).json(body); } }); });
I provide the simple forwarding server and simple web app on github, as a starting point for hackathons. Both applications are a part of a project, which addresses the usage of Node-RED in combination with IBM Watson Assistant and IBM Watson IoT .
- Start the simple forwarding server and simple web app in the terminal
- Usage of the running web-application on http://localhost:3001, Node-RED on IBM Cloud, and the forwarding server on http://localhost:3000.
- Using the postman application.
BTW: You can get my sample postman collection here.
With this workaround I have full control and I am still very flexible during a hackathon, when using Node-RED for prototyping and building integrations to services and web-applications.
I hope this was useful for you and let’s see what’s next?
Greetings,
Thomas
PS and FYI … You can use the IBM Cloud for free just create a IBM Lite Account only a email is requested.
#Node-RED, #cors, #nodejs, #postman, #hackathon, #prototyping, #IBMDeveloper
Thanks for the reference link and great article!
LikeLiked by 2 people