Reputation: 2909
I'm getting a JSON from [1], due to the naming of the keys in the json I was unable to straightaway use either of the 2 approches in hadling JSON in ballerina:
Approach 1: Work with json values directly:
string s = check j.x.y.z;
Approach 2: Work with application-specific, user-defined subtype of anydata:
couldn't use cloneWithType or directly assign to a user defined record type
My workaround was:
type AllStockData record {
string open;
string high;
string low;
string close;
string volume;
};
AllStockData[] stockData = [];
public function main() returns @tainted error? {
http:Client httpClient = check new ("https://www.alphavantage.co");
json jsonPayload = check httpClient->get("/query?function=TIME_SERIES_INTRADAY&symbol="+searchSymbol.toUpperAscii()+"&interval=5min&apikey="+apiKey, targetType = json);
map<json> allData = <map<json>>jsonPayload;
foreach json item in <map<json>>allData["Time Series (5min)"] {
map<json> stockItem = <map<json>>item;
AllStockData stock = {
open: stockItem["1. open"].toString(),
high: stockItem["2. high"].toString(),
low: stockItem["3. low"].toString(),
close: stockItem["4. close"].toString(),
volume: stockItem["5. volume"].toString()
};
stockData.push(stock);
}
I was wondering If there is a better way to do this?
Upvotes: 4
Views: 905
Reputation: 1610
I prefer to work with application-specific types when dealing with JSON in Ballerina. You can use quoted identifiers in Ballerina to map the complete json payload into an application-specify type. I've used a query expression to filter out stack data entries into an array. There are other ways with slight variations to achieve the same thing.
Note that I've used Ballerina Swan Lake Alpha 3 to test this code.
import ballerina/io;
import ballerina/http;
type StockQuery record {|
MetaData 'Meta\ Data;
TimeSeries5min 'Time\ Series\ \(5min\);
|};
type MetaData record {|
string '1\.\ Information;
string '2\.\ Symbol;
string '3\.\ Last\ Refreshed;
string '4\.\ Interval;
string '5\.\ Output\ Size;
string '6\.\ Time\ Zone;
|};
type TimeSeries5min record {|
StockData...;
|};
type StockData record {|
string '1\.\ open;
string '2\.\ high;
string '3\.\ low;
string '4\.\ close;
string '5\.\ volume;
|};
public function main() returns error? {
http:Client httpClient = check new ("https://www.alphavantage.co");
json jsonPayload = check httpClient->get("/query?function=TIME_SERIES_INTRADAY&symbol=IBM&interval=5min&apikey=demo",
targetType = json);
StockQuery stockQuery = check jsonPayload.cloneWithType(StockQuery);
TimeSeries5min timeSeries = stockQuery.Time\ Series\ \(5min\);
StockData[] stockDataArr = from var key in timeSeries.keys()
let StockData? stockData = timeSeries[key]
where stockData is StockData
select stockData;
io:println(stockDataArr);
}
Upvotes: 4