Limit API or AJAX requests (and send statusCode 429)

I haven't found a way to do this right
Would someone know how to limit receiving many api requests, sending Error 429 (too many requests) to all clients?

In this way that I have, it is only sent to the last

[{"id":"2c6e40c2.7824f","type":"http in","z":"ccdd1e82.45d92","name":"","url":"/api/ajax","method":"get","upload":false,"swaggerDoc":"","x":150,"y":2940,"wires":[["4b619d55.b302a4"]]},{"id":"de998de2.ce80a","type":"http response","z":"ccdd1e82.45d92","name":"","statusCode":"","headers":{},"x":1010,"y":2940,"wires":[]},{"id":"4b619d55.b302a4","type":"template","z":"ccdd1e82.45d92","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":" <h1>AJAX</h1>\n <button type=\"button\" onclick=\"loadDoc()\">Change Content</button>\n<div id=\"demo\">\n  <h2>Let AJAX change this text</h2>\n  \n</div>\n\n<script>\n    \n  function loadDoc() {\n  var xhttp = new XMLHttpRequest();\n  xhttp.onreadystatechange = function() {\n    if (this.readyState == 4 && this.status == 200) {\n     document.getElementById(\"demo\").innerHTML = this.responseText;\n    }\n  };\n  xhttp.open(\"GET\", \"/api/sender\", true);\n  xhttp.send();\n}  \n    \n</script>","output":"str","x":380,"y":2940,"wires":[["de998de2.ce80a"]]},{"id":"20fe94b7.72f73c","type":"http in","z":"ccdd1e82.45d92","name":"","url":"/api/sender","method":"get","upload":false,"swaggerDoc":"","x":160,"y":3020,"wires":[["b127bd28.b011f"]]},{"id":"f78c0abb.04f078","type":"http response","z":"ccdd1e82.45d92","name":"","statusCode":"","headers":{},"x":1010,"y":3020,"wires":[]},{"id":"f173924c.115bf","type":"template","z":"ccdd1e82.45d92","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"text","output":"str","x":800,"y":3020,"wires":[["f78c0abb.04f078","44e95b19.acd924"]]},{"id":"a1ad0bdd.8379a8","type":"delay","z":"ccdd1e82.45d92","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"5","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":560,"y":3020,"wires":[["f6e534f3.868098"]]},{"id":"5ca15075.02425","type":"status","z":"ccdd1e82.45d92","name":"","scope":["a1ad0bdd.8379a8"],"x":140,"y":3080,"wires":[["79b66316.b882ac"]]},{"id":"79b66316.b882ac","type":"change","z":"ccdd1e82.45d92","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"status","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":255,"y":3080,"wires":[["b127bd28.b011f","5015e505.793d2c"]],"l":false},{"id":"b127bd28.b011f","type":"function","z":"ccdd1e82.45d92","name":"set counter","func":"if(msg.topic == \"status\"){\n    if( (!isNaN(msg.status.text)&&parseInt(msg.status.text))){\n        context.set(\"count\",parseInt(msg.status.text))\n    }\n    else{\n        context.set(\"count\",0)\n    }\n}\nelse{\n        if(context.get(\"count\")>5){\n            msg.reset=true //resetea sin enviar nada mas que al ultimo , \n            // msg.flush=true //resetea enviando los mensajes de golpe , \n            node.send(msg)\n            msg.statusCode=429\n            node.warn(\"Error 429 Too Many Requests\")\n            throw new Error(\"Error 429 Too Many Requests\")\n        }\n\n    return msg\n}","outputs":1,"noerr":0,"x":390,"y":3020,"wires":[["a1ad0bdd.8379a8"]]},{"id":"44e95b19.acd924","type":"debug","z":"ccdd1e82.45d92","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1010,"y":2980,"wires":[]},{"id":"a76b7f22.98978","type":"catch","z":"ccdd1e82.45d92","name":"","scope":["b127bd28.b011f"],"uncaught":false,"x":130,"y":3140,"wires":[["742bd8c3.f34078","a31a2942.323908"]]},{"id":"742bd8c3.f34078","type":"http response","z":"ccdd1e82.45d92","name":"","statusCode":"","headers":{},"x":1010,"y":3140,"wires":[]},{"id":"a31a2942.323908","type":"debug","z":"ccdd1e82.45d92","name":"ERRR","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":250,"y":3180,"wires":[]},{"id":"5015e505.793d2c","type":"debug","z":"ccdd1e82.45d92","name":"TOPIC","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":370,"y":3080,"wires":[]},{"id":"f6e534f3.868098","type":"function","z":"ccdd1e82.45d92","name":" imagine that I am a function that uses a lot of cpu","func":"\nreturn msg;","outputs":1,"noerr":0,"x":750,"y":3060,"wires":[["f173924c.115bf"]]}]

image

In this example, the requests would accumulate in the delay node with each click on the button.

When sending more than 5 requests, it should send error 429, but I only get this with one client.

the test I'm doing is to open 2 or 3 tabs and try clicking alternately

EDIT: this is the result i get, but i want it on both clients

You could use a Delay node and limit the rate of messages (see dropdown in the node), or, more complex @Colin has written a Queuing flow that can adapted to guarantee delivery of all requests

I use that flow and a delay node, set up as above, just before the http request to handle my queues.

In the end, after giving it several turns, i limit the number of incoming requests and deny new ones until the counter drops, is easier

[{"id":"329f99f7.9fa896","type":"status","z":"a3a83bc2.6d7168","name":"","scope":["86e49f0d.a24aa"],"x":200,"y":1200,"wires":[["a69a8e95.86db8"]]},{"id":"a69a8e95.86db8","type":"change","z":"a3a83bc2.6d7168","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"status","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":315,"y":1200,"wires":[["4dd741b4.5662b"]],"l":false},{"id":"4dd741b4.5662b","type":"function","z":"a3a83bc2.6d7168","name":"set counter","func":"if(msg.topic == \"status\"){\n    if( (!isNaN(msg.status.text)&&parseInt(msg.status.text))){\n        context.set(\"count\",parseInt(msg.status.text))\n    }\n    else{\n        context.set(\"count\",0)\n    }\n}\nelse{\n        if(context.get(\"count\")>5){\n            // msg.reset=true //resetea sin enviar nada mas que al ultimo , \n            // msg.flush=true //resetea enviando los mensajes de golpe , \n            // node.warn(\"Error 429 Too Many Requests\")\n            return [null,msg]\n\n        }else{\n         \n        return [msg,null]   \n        }\n\n}","outputs":2,"noerr":0,"x":450,"y":1120,"wires":[["86e49f0d.a24aa","ac9001e6.5e4af"],["bec91fab.abab4"]]},{"id":"bec91fab.abab4","type":"http response","z":"a3a83bc2.6d7168","name":"","statusCode":"429","headers":{},"x":640,"y":1140,"wires":[]},{"id":"86e49f0d.a24aa","type":"delay","z":"a3a83bc2.6d7168","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"5","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":640,"y":1100,"wires":[["7aa9a2e0.fa3f8c","4f048257.82ff3c"]]},{"id":"ac9001e6.5e4af","type":"debug","z":"a3a83bc2.6d7168","name":"item","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":610,"y":1040,"wires":[]},{"id":"1abb2bca.f81de4","type":"http in","z":"a3a83bc2.6d7168","name":"","url":"/api/some","method":"get","upload":false,"swaggerDoc":"","x":220,"y":1120,"wires":[["4dd741b4.5662b"]]},{"id":"4f048257.82ff3c","type":"http response","z":"a3a83bc2.6d7168","name":"","statusCode":"","headers":{},"x":830,"y":1100,"wires":[]}]
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.