I'm working in Node Red and I need to understand how to loop JSON object and, for each JSON object, make a HTTP request towards another endpoint.
In other words: here's the use case I will need to represent.
Node Red makes a HTTP post to get all devices.
All devices are returned in a JSON, with several information and a DEVICE_ID.
For every device ID, Node Red has to make another HTTP request passing the above id, to get all the resources for that device.
I'm in trouble since I expected Node Red to have a dedicated block for loops, but is not like that. So how can I make a workaround?
If I use the "function" block, and I type there the code to make my loop, how to "come back" to the flow view, using Http blocks? Thank you!
In flow-based programming, you tend to avoid loops. The most "flow like" approach would be to split the JSON output into multiple messages.
If you are familiar with JavaScript, the easiest way to do this is with a function node. In the JS code, create a loop over the JSON and within the loop, use node.send(msgobject) to output a new message. You can remove the normal return msg at the end of the code as you don't need it in this instance. Obviously, you have to create your msgobject for each loop instance (or create it inline). When the loop exits and you reach the end of your function node code, Node-RED will continue on to the next node in the flow, you don't need to do anything special.
Otherwise, you can use the core split node (or one of the contributed split nodes) to split the data into multiple messages.
Some specialized nodes exist for this purpose, for example node-red-contrib-loop.
Related
I'm making a website that gets its info from a RESTapi I've written and hosted myself, have had no data problems thus far.
Now I'm trying a simple retrieve of a json object and I get all the info correctly as shown here in the API. (Visualized & tested in Swagger)
As you can clearly see, it retrieves it the complete object and underlying objects correctly (blurred sensitive info).
Pay attention to the property "AmountOfEggs" though.
Now when i call this api endpoint (exactly the same way) in my site and console.log the result.data, this is the feedback.
Now for some reason I can't recieve AmountOfEggs in my frontend.
I've recreated the entire object, wrote different names, passed different props (Id, NumberBus, etc are passed in this situation with no problem, which are also int (number) types).
I have no idea why this property gets "dropped" in the transfer and filled with/defaults to an empty string.
Any help would be greatly appreciated.
I found where it went wrong and it's due to different factors.
To start, I am making this site using the Vue framework, which has reactive components, which means, data gets adjusted and you get live updated components on your views/pages.
In the page that contained the call, I also wanted to add dynamic styling. The code I used for this is the following:
v-for="seller in retrievedSellers"
:key="seller.Id"
:class="[
'sellerStyle'
, (seller.AmountOfEggs = 0 ? 'grey-out-seller' : ''),
]"
Now two things to note, first of all this might look like backend coding but this is Vue logic on the .vue file which handles the dynamic options that Vue provides so I never thought to look here for the error.
The error of couse is the 'seller.AmountOfEggs = 0' part, using one equal sign (assignment) instead of two (comparison).
So I learned,
Vue doesn't throw errors on assignments in code that is used to generate frontend (where you should NEVER alter your data).
My console.log was the moment the response of the API came in, where apparently it was already assigned a new value (due to my code above) before hitting the console.log.
It still greatly surprises me that Vue handles ^this^ first to make sure your reactive components are up to date before finishing the api call itself.
However, I still don't understand how it said "" instead of 0.
I'm using typescript (javascript strongly-typed) so it definitely wants to contain a number and not an empty string. Even in the declaration of my DTO the property is defined as (and expects) a number.
I'm using useContext and setState hooks to share an array of audiotracks across my site. i have a few playlist components which can add/remove tracks to the global playlist as well as a wrapper for the audio element that can e.g. retrieve next track when current finishes.
The playlists all use the same Component. Each Track is basically just a <tr> with <td>s containing id,title,url.. and so on. I generate these using json.
Now my question is what should I pass around in my hooks? Because I see at least 3 options... I could pass the
passing track_id seems most efficient but.. but whenever I need the tracks data.. e.g. to get the url or to render I need to find the object which could be anywhere nested in my json backend.
passing the dom-node seems wrong... but would be very easy to use in case i want to render the list somewhere else.
if you pass the track json object.. I have all the data I need at any point.. but i somehow need to attach it to all track dom nodes.. and that again seems not right too..
Option #1. track.json object
{"title":"...","artist":"...","year":"..."}
Option #2. <tr> dom-node
<tr><td>title</td><td>arist</td><td>year</td></tr>
key={track_id}
Now I would obviously like to follow best-practice and be as efficient as possible.. so can somebody point me in the right direction
I think all will do the same thing. If you pass an id or json then it will still need to be rendered in a dom node to be viewed, so when you say pass a dom node your really just passing a string. Am I correct in saying that no matter what is passed it will need to go through some sort of function to get the song from the back end? If so, then my suggestion would be json.
I have java library that runs webservices and these return a response in XML. The webservices all revolve around giving a list of details about items. Recently, changes were made to allow the services to return JSON by simply converting the XML to JSON. When looking at the responses, I saw they're not as easy to parse as I thought. For example, a webservice that returns details about items.
If there are no items, the returned JSON is as follows:
{"ItemResponse":""}
If there is 1 item, the response is as follows (now itemResponse has a object as value instead of a string):
{"ItemResponse":{"Items":{"Name":"Item1","Cost":"$5"}}}
If there two or more items, the response is (now items has an array as value instead of an object):
{"ItemResponse":{"Items":[{"Name":"Item1","Cost":"$5"},{"Name":"Item2","Cost":"$3"}]}}
To parse these you need several if/else which I think are clunky.
Would it be an improvement if the responses were:
0 items: []
1 item: [{"Name":"Item1","Cost":"$5"}]
2 items: [{"Name":"Item1","Cost":"$5"},{"Name":"Item2","Cost":"$3"}]
This way there is always an array, and it contains the itemdata. An extra wrapper object is possible:
0 items: {"Items":[]}
1 item: {"Items":[{"Name":"Item1","Cost":"$5"}]}
2 items: {"Items":[{"Name":"Item1","Cost":"$5"},{"Name":"Item2","Cost":"$3"}]}
I'm not experienced in JSON so my question is, if you were a developer having to use these webservices, how would you expect the JSON resonse to be formatted? Is it better to always return a consistent array, even if there are no items or is this usually not important? Or is an array not enough and do you really expect a wrapper object around the array?
What are conventions/standards regarding this?
Don't switch result types, always return an array if there are more items possible. Do not mix, for 1 item an object for more an array. That's not a good idea.
Another best practise is that you should version your API. Use something like yoursite.com/api/v1/endpoint. If you don't do this and you change the response of your API. All your client apps will break. So keep this in mind together with documentation. (I've seen this happen a lot in the past..)
As a developer I personally like your second approach, but again it's a preference. There is no standard for this.
There are several reasons to use json:
much more dense and compact: thus data sent is less
in javascript you can directly access those properties without parsing anything. this means you could convert it into an object read the attributes (often used for AJAX)
also in java you usually don't need to parse the json by yourself - there are several nice libs like www.json.org/java/index.html
if you need to know how json is build ... use google ... there tons of infos.
To your actual questions:
for webservices you often could choose between xml and json as a "consumer" try:
https://maps.googleapis.com/maps/api/place/textsearch/json
and
https://maps.googleapis.com/maps/api/place/textsearch/xml
there is no need to format json visually - is it not meant for reading like xml
if your response doesn't have a result, json-service often still is giving a response text - look again at the upper google map links - those are including a response status which makes sense as it is a service.
Nevertheless it's the question if it is worth converting from xml to json if there isn't a specific requirement. As Dieter mentioned: it depends on who is already using this service and how they are consumed ... which means the surrounding environment is very important.
Let's suppose i'm dealing with 3 (very) different messages formats inside my Mule ESB, i'll call them A, B and C. They could be XML (via socket), some custom text-format and SOAP transporting another kind of XML (it's not the same that is transported via socket), for example. All of them can be transformed into each other. A, B and C carry the same information, only in different formats.
Each one of them will have it's own entry point in the flow, some format validations etc..
But, there's some (a lot) of logic that i need to be executed in all of them like dealing/extracting some information, routing based in the content, enriching etc etc..
What should i do? I mean, i did some research on integration patterns but didn't found anything about this situation or similar.
The easier approach sounds like taking one of the formats (let's take B) as the "default" one of my "main-flow" and implementing all the common logic based on it. Then, every message that arrives will be transformed to B and then transformed again to the destination format, even if the two points uses the same format.
Examples:
1) One "A" hit my app, then it's transformed to "B" to execute the common-logic, then it's transformed again to "A" to be delivered.
2) One "C" hit my app, then it's transformed to "B" to execute the common-logic, then it's transformed to "A" to be delivered.
Then, my question is, does Mule have a feature that provides me a better way on doing something like this or the solution above looks reasonable?
Thanks in advance.
The are a few options, any of these can be implemented in Mule. The first two are close to what you have suggested.
Normalizer: http://eaipatterns.com/Normalizer.html
Canonical Data Model: http://eaipatterns.com/CanonicalDataModel.html
Routing slip: http://eaipatterns.com/RoutingTable.html
Envelope: http://eaipatterns.com/EnvelopeWrapper.html
Which you use will depend on your messages and what you need to do with them.
With Canonical Data Model for example you could build a seperate flow for each incoming type that:
Receives a object in their own format.
Translates that object to the canonical object.
Passes that message on to the main processing flow.
The main flow would only need to know how to process that object.
Any endpoints that need the original object back would sit behind a transformer that can reverses the transformation.
You could pick one of your existing objects and use message variables to remember the original format or create a new object that remembers the original type itself.
I am building an API that uses JSON for requests/responses. I want to be able to also receive bulk requests, i.e., JSON Arrays.
Right now, I have a solution which works fine if the JSON request is always wrapped in an array:
[
{"id":"AAAEEF", "value":"abc"}
]
works, also
[
{"id":"AAAEEF", "value":"abc"},
{"id":"AAAEF1", "value":"vbc"},
]
If one wants to request only a single id-value combination and thus requests
{"id":"AAAEEF", "value":"abc"}
the request fails.
My question: Is it acceptable for a "good" API to enforce wrapping all JSON requests in an array, even if they only have one element?
Thanks in advance for helping me out!
The key to writing a "good" API is to be consistent, and to document it well. Whatever choices you make next are yours to make - if you decide you have good reason to require all calls to your API should be wrapped in a thisIsAContainerObject element, by all means document it and release it.
For consistency it might even be explicitly better to always require an array. As long as you throw a proper error when more than one element is inserted.