How to save single flow in my local database

i want to save every single flow (tab`s flow) into my local database, how can i do or what plugin can i use? Thank to help

I have a (rudimentary) subflow that uses the node-red admin api, it assumes you have setup adminAuth in your settings.js.

Note this will try to get the bearer access token and write it to a flow variable. If access fails, the flow might end up in a loop (which is why it is rudimentary ;))

Import the flow below, it adds a "node-red-api" subflow to the palette
Drag it into the flow
Doubleclick the node, enter your credentials and the url of the node-red instance.
Attach an inject node and a debug node.
Deploy.

It will output each flow tab as a msg.payload, which contains the flow as an object.

[{"id":"032dd27dda5cb68c","type":"subflow","name":"node-red-api","info":"","category":"","in":[{"x":72,"y":72,"wires":[{"id":"644ad4ea5196ed50"}]}],"out":[{"x":1340,"y":72,"wires":[{"id":"cce6ce997d307379","port":0},{"id":"b22a1eadbf4bdd26","port":0}]}],"env":[{"name":"username","type":"str","value":"","ui":{"label":{"en-US":"Username"},"type":"input","opts":{"types":["str"]}}},{"name":"password","type":"cred","ui":{"label":{"en-US":"Password"}}},{"name":"url","type":"str","value":"http://<ip>:1880","ui":{"label":{"en-US":"node-red-url"},"type":"input","opts":{"types":["str"]}}}],"meta":{},"credentials":{"password":""},"color":"#87A980","icon":"node-red/redis.png"},{"id":"16a2e08a3a5bec35","type":"function","z":"032dd27dda5cb68c","name":"","func":"msg.method = \"POST\"\nmsg.payload = {\n    \n    client_id:\"node-red-admin\",\n    grant_type:\"password\",\n    scope:\"read\",\n    username:env.get(\"username\"),\n    password:env.get(\"password\")\n}\nmsg.url = `${env.get(\"url\")}/auth/token`\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":24,"wires":[["dfa1e2b905edcc46"]]},{"id":"a5e1d338a25671de","type":"http request","z":"032dd27dda5cb68c","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":602,"y":120,"wires":[["3d14412c41abe1f2"]]},{"id":"c4dd11976e8f6754","type":"function","z":"032dd27dda5cb68c","name":"","func":"msg.method = \"GET\"\nmsg.headers = {\n    \"Authorization\": `Bearer ${flow.get(\"nr_api_token\")}`\n}\nmsg.url = `${env.get(\"url\")}/flows`\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":444,"y":120,"wires":[["a5e1d338a25671de"]]},{"id":"644ad4ea5196ed50","type":"switch","z":"032dd27dda5cb68c","name":"check token","property":"nr_api_token","propertyType":"flow","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":194,"y":72,"wires":[["16a2e08a3a5bec35"],["c4dd11976e8f6754"]]},{"id":"cce6ce997d307379","type":"change","z":"032dd27dda5cb68c","name":"set token","rules":[{"t":"set","p":"nr_api_token","pt":"flow","to":"payload.access_token","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":732,"y":24,"wires":[["c4dd11976e8f6754"]]},{"id":"3d14412c41abe1f2","type":"switch","z":"032dd27dda5cb68c","name":"","property":"statusCode","propertyType":"msg","rules":[{"t":"eq","v":"401","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":746,"y":120,"wires":[["16a2e08a3a5bec35"],["17dfeaf4dd4b5b71"]]},{"id":"dfa1e2b905edcc46","type":"http request","z":"032dd27dda5cb68c","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":574,"y":24,"wires":[["cce6ce997d307379"]]},{"id":"17dfeaf4dd4b5b71","type":"change","z":"032dd27dda5cb68c","name":"","rules":[{"t":"set","p":"tabs","pt":"msg","to":"payload[type='tab'].id","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":918,"y":120,"wires":[["040e7a2e99c6da14"]]},{"id":"040e7a2e99c6da14","type":"function","z":"032dd27dda5cb68c","name":"","func":"method = \"GET\"\nheaders = {\n    \"Authorization\": `Bearer ${flow.get(\"nr_api_token\")}`\n}\n\nmsg.tabs.forEach(t => {\n    url = `${env.get(\"url\")}/flow/${t}`\n    node.send({method,headers,url})\n})\n\n\n\nreturn null","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1068,"y":120,"wires":[["b22a1eadbf4bdd26"]]},{"id":"b22a1eadbf4bdd26","type":"http request","z":"032dd27dda5cb68c","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":1222,"y":120,"wires":[[]]},{"id":"8abf87dadc5b1c7e","type":"subflow:032dd27dda5cb68c","z":"dd68845f3195d3c5","name":"","x":574,"y":816,"wires":[[]]}]

You will have to build your own storage plugin (Storage API : Node-RED) that supports what ever database you want to use.

There are some example versions out there e.g. here is one I wrote to store flows in mongodb Node-RED Storage Plugin – Ben's Place

And you will need to parse the single JSON object which represents the entire application into seperate tabs if you want to store them separately (you will also need to recombine them for any load event as the API expect yo get the whole object back, not just a single tab).

ok, that means i need to change too many model and function, thats difficult, thank u for answer :grin:

Not sure who you are responding to, but my api approach is quite simple. Every payload you can store as a string into a database you can make relations mappings where needed.

Think you , i have tried your way, that can solve to save flows into database ,but how can i modify my single flow every opeartion and save it into database , i think i need to edit code logic when i save flow, i only need to save flow which flow has modified , but its connect so many model

this question means i hope to add/delete/edit/find flows by database-storage

Ben has already given you the answer but you don't want to do it.

1 Like

thank for his answer again
i have tried this plugin ,but it saves all json, i wish to save single flow every data

And you will need to parse the single JSON object which represents the entire application into seperate tabs if you want to store them separately (you will also need to recombine them for any load event as the API expect yo get the whole object back, not just a single tab).

As I clearly stated, that is an example to get you started, you WILL have to edit it to do what you want.

ok i understand it thanks a lot