Which HTTP Method should I use when sending an instruction to modify the state of an in-memory resource object - rest

We want to have an API, which is connected to Real Time Market Data systems and performs financial pricings.
As the pricing depends on those market data (and on parameters sent with the request in order to select the right mathematical model), can we say that the result of the pricing can be considered as a Resource ? Can the "Price" method can be actually a GET ?
We would want also to update the market data configuration to be able to configure the service on the fly (adding new market data systems to plug to).
The "resource" here can be the Market Data Container, but the instruction to modify it is not a resource... So what Http Method could it be ?
Thanks,
Laurent

Related

Fiware-Orion: Geolocation

Hi I'm a student and I'm working for the first time on the broker. I understood how the creation of entities works and their updating through "update" queries. My question is: you can create an entity that contains variables (eg geolocation) defined with value "null" or "zero" and then initialize them with values that interest me. So as to have dynamic and non-static variables (ie that require user update)?
Or do we need interaction with the CEP to do this?
From what I have read in the fiware-orion guide when I create an entity (ex car having attributes and velocity coordinates: geopoint). The values of these 2 attributes must be set in a static way (ex: speed 100 and position coordinates 40.257, 2.187). If I understand the values of these attributes I can only update them by making an update query. So my question is:
Is it possible to update the value of the attributes that contain the position or the speed of the car in a dynamic way, ie without having to write the values from the keyboard? Or does this require the use of the CEP of orion?
If I could not explain myself more generally I would like to know if it is possible to follow the progress of a moving car without me having to add the values from the keyboard.
Thanks.
Orion Context Brokker exposes a REST-based API that (among other things) allows you to create, update and query entities. From the point of view of Orion, it doesn't matter who is the one invoking the API: it can be done manually (for instance, using Postman or curl) or can be an automated system developed by you or a third party (for instance, a software running in a sensor in the car that measures the speed and periodically sends an update using a wireless communication network).
From a client-server point of view (in the case you are familiar with these concepts), Orion takes the server of the API role and the one updating the speed (either manually or automatically) takes the role of client of the API.

How to merge/consolidate responses from multiple RESTful microservices?

Let's say there are two (or more) RESTful microservices serving JSON. Service (A) stores user information (name, login, password, etc) and service (B) stores messages to/from that user (e.g. sender_id, subject, body, rcpt_ids).
Service (A) on /profile/{user_id} may respond with:
{id: 1, name:'Bob'}
{id: 2, name:'Alice'}
{id: 3, name:'Sue'}
and so on
Service (B) responding at /user/{user_id}/messages returns a list of messages destined for that {user_id} like so:
{id: 1, subj:'Hey', body:'Lorem ipsum', sender_id: 2, rcpt_ids: [1,3]},
{id: 2, subj:'Test', body:'blah blah', sender_id: 3, rcpt_ids: [1]}
How does the client application consuming these services handle putting the message listing together such that names are shown instead of sender/rcpt ids?
Method 1: Pull the list of messages, then start pulling profile info for each id listed in sender_id and rcpt_ids? That may require 100's of requests and could take a while. Rather naive and inefficient and may not scale with complex apps???
Method 2: Pull the list of messages, extract all user ids and make bulk request for all relevant users separately... this assumes such service endpoint exists. There is still delay between getting message listing, extracting user ids, sending request for bulk user info, and then awaiting for bulk user info response.
Ideally I want to serve out a complete response set in one go (messages and user info). My research brings me to merging of responses at service layer... a.k.a. Method 3: API Gateway technique.
But how does one even implement this?
I can obtain list of messages, extract user ids, make a call behind the scenes and obtain users data, merge result sets, then serve this final result up... This works ok with 2 services behind the scenes... But what if the message listing depends on more services... What if I needed to query multiple services behind the scenes, further parse responses of these, query more services based on secondary (tertiary?) results, and then finally merge... where does this madness stop? How does this affect response times?
And I've now effectively created another "client" that combines all microservice responses into one mega-response... which is no different that Method 1 above... except at server level.
Is that how it's done in the "real world"? Any insights? Are there any open source projects that are built on such API Gateway architecture I could examine?
The solution which we used for such problem was denormalization of data and events for updating.
Basically, a microservice has a subset of data it requires from other microservices beforehand so that it doesn't have to call them at run time. This data is managed through events. Other microservices when updated, fire an event with id as a context which can be consumed by any microservice which have any interest in it. This way the data remain in sync (of course it requires some form of failure mechanism for events). This seems lots of work but helps us with any future decisions regarding consolidation of data from different microservices. Our microservice will always have all data available locally for it process any request without synchronous dependency on other services
In your case i.e. for showing names with a message, you can keep an extra property for names in Service(B). So whenever a name update in Service(A) it will fire an update event with id for the updated name. The Service(B) then gets consumes the event, fetches relevant data from Service(A) and updates its database. This way even if Service(A) is down Service(B) will function, albeit with some stale data which will eventually be consistent when Service(A) comes up and you will always have some name to be shown on UI.
https://enterprisecraftsmanship.com/2017/07/05/how-to-request-information-from-multiple-microservices/
You might want to perform response aggregation strategies on your API gateway. I've written an article on how to perform this on ASP.net Core and Ocelot, but there should be a counter-part for other API gateway technologies:
https://www.pogsdotnet.com/2018/09/api-gateway-response-aggregation-with.html
You need to write another service called Aggregator which will internally call both services and get the response and merge/filter them and return the desired result. This can be easily achieved in non-blocking using Mono/Flux in Spring Reactive.
An API Gateway often does API composition.
But this is typical engineering problem where you have microservices which is implementing databases per service pattern.
The API Composition and Command Query Responsibility Segregation (CQRS) pattern are useful ways to implement queries .
Ideally I want to serve out a complete response set in one go
(messages and user info).
The problem you've described is what Facebook realized years ago in which they decided to tackle that by creating an open source specification called GraphQL.
But how does one even implement this?
It is already implemented in various popular programming languages and maybe you can give it a try in the programming language of your choice.

OPC UA - Client - Milo - Best Practice - Subscription to Data Change

I started a OPC UA project using the Milo project to create a OPC UA Client. I am still very new to OPC UA. Right now I am stuck looking for the best practice to read values from several Nodes after a data change of one specific node.
The information model looks like this:
RfidSensorType
On my server i will have several objects of this RfidSensorType. The client creates a subscription on the CurrentAtTag Node to listen for data changes.
My Question:
When the value of CurrentAtTag is changed a callback function will be called in my client which contains the UaMonitoredItem and the DataValue of the CurrentAtTag.
In my application i need to process (at the same time) also the values of Station, IOLPort and CurrentValue which are changed at that moment too.
How can i access those values within the callback from CurrentAtTag?
My only solution is: Using a synchronous read request within that callback
-> Is that an legit approach?
My Research:
1) TriggeringService
I've seen that a TriggerigService exists, which monitors items will send reports only if one specific node changes it values.
Problem: This will call several callsbacks and noz just one..i need all the informations at the same time to further process them..
2) Event Monitoring
In event monitoring one can select "Event fields" which will be returned for each Event notificaiton. I am not sure if i could select the CurrentAtTag, Station, IOLPort and CurrentValue...
Just like you can subscribe to the server's ServerStatus (nodeid "i=2256"), you should be able to subscribe to the nodeid corresponding to 'RfidSensor_Station1'. The server will send PublishResponse with data of type 'RfidSensorType' encoded as an ExtensionObject. The trick is decoding the ExtensionObject.
As Kevin corrected, because 'RfidSensor_Station1' is not node class 'Variable' then it doesn't have a value attribute and you can not monitor the node for data changes. If you are using a PLC, I might combine all properties of the sensor into a string, or byte array. Then I monitor the new variable, and parse the string in the client.
Or you could make ReadRequest as you describe. That will work just fine.

Having a Ref to a previous state in Hypermedia capable API

In a Hypermedia capable REST API, consider a non browser client needs to access a resource Model-A. Typically we would have an entry point and then a ref to get models and then another ref to access the particular model.
But what if after checking the received model, we need to go back and check another model say Model-B ? In that case, wouldn't it be better to have a ref to the previous state ?
For an example, take an API for a toy store.
First we would get a root link to list down all the toys.(May be a search with a criteria.) With the response, we would get a set of Toy representation with links to access them.
If I choose, say a train and then want to select something else, need to follow through from the start.

Dynamically Populating Locations on the basis of Storage Type

I am a beginner in Softlayer and we need to implement block storage functionality provided by softlayer in an Application. We just need to make REST call to fetch the locations on the basis of storage type selected. I need to know relationship between Storage Type and locations. What method I need to call in REST API and object mask required for same.. Thanks in Advance.
If you want to order a new “Network storage” and know what “locations” are available for this item, see these steps:
1. The first that we need to know is the “package id” to use for this order.
The “package id” is very important to valid and verifies what kind of items, what locations are available at the moment to order network storage.
For example:
Storage Type: Endurance, the package to use is “240”
Storage Type: Performance, the package to use is “222”
To get all active packages, please review:
http://sldn.softlayer.com/reference/services/SoftLayer_Product_Package/getAllObjects
2. Once we know what package to use, we need to get the valid “item price ids” according to LOCATION. The following request can help us:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Product_Package/[package_id]/getItemPrices?objectMask=mask[id,item[keyName,description],pricingLocationGroup[locations[id, name, longName]]]
Method: GET
Where:
A price id with a locationGroupId = null is considered "A standard price" and the API will internally switch the prices for the customer. But we recommend to execute first the verifyOrder in order to see if the wanted order is ok (the fee can vary).
Reference: http://sldn.softlayer.com/blog/cmporter/Location-based-Pricing-and-You
Also, this method can help you to get available locations for a specific package:
http://sldn.softlayer.com/reference/services/SoftLayer_Product_Package/getRegions
3. Then you will able to order a new Network storage, please see:
API for Performance and Endurance storage(Block storage)
Now, if you want to list the network storage of your account, please see:
http://sldn.softlayer.com/reference/services/SoftLayer_Account/getNetworkStorage
This is an example, where the result displays properties like: “location” and “network storage type”.
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Account/getNetworkStorage?objectMask=mask[storageType, billingItem[description,location[id,longName]]]
Using filters:
Filtering by network Storage Type: “Endurance Storage” or “Block Storage (Performance)”
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Account/getNetworkStorage?objectMask=mask[id,username,nasType,storageType, billingItem[description,location[id,longName]]]&objectFilter={"networkStorage":{"nasType":{"operation":"ISCSI"},"billingItem":{"description":{"operation":"Endurance Storage"}}}}
Regards.
You need to use the http://sldn.softlayer.com/reference/services/SoftLayer_Product_Package/getRegions method
It returns the valid locations for a package, each storage type belongs to an specific package (that is the relation you are looking for) to get the packages use http://sldn.softlayer.com/reference/services/SoftLayer_Product_Package/getAllObjects method
see this post for more information
Filter parameters to POST verify and place order request for Performance storage