Reputation: 430
I have problem in joining two json objects with the integrated query language of Ballerina. I have two subservices, which responses with json objects on call. My goal is to join them based on a common key and return another json as result.
I have tried this code, but no success:
function getAllTransactionsPerDcr(string requestedContentType) returns json|xml|error {
var dcrRequest = dcrService -> get("/dataControlRecords");
var traRequest = traService -> get("/transactions");
if (dcrRequest is http:Response && traRequest is http:Response){
json|error dcrs = dcrRequest.getJsonPayload();
json|error tras = traRequest.getJsonPayload();
if(dcrs is json && tras is json ){
if(requestedContentType == "application/json"){
json output = from var dcr in <json[]>dcrs
join var tra in <json[]>tras
on <string>dcr.CDCRID equals <string>tra.CDCRID
select {
id: check dcr.CDCRID,
source: check dcr.VCSOURCES,
target: check dcr.VCTARGETS,
transactionId: check tra.CTRAID
};
return output;
}
}
}
}
And this is the ressource function:
@http:ResourceConfig {
methods: ["GET"],
path:"/data-control-records"
}
resource function getAllTransactionsPerDcr(http:Caller caller, http:Request request) returns error?{
http:Response response = new;
var result = getAllTransactionsPerDcr(request.getHeader("Accept"));
if(result is json){
check caller -> respond(result);
} else if (result is error){
response.setTextPayload(result.message());
}
}
I get the following error, if I call the service:
error: {ballerina}StackOverflow
at ballerina.lang_query.0_0_1._InitFunction:process(types.bal:137)
ballerina.lang_query.0_0_1._InputFunction:process(types.bal:197)
ballerina.lang_query.0_0_1._StreamPipeline:next(types.bal:74)
ballerina.lang_query.0_0_1._InnerJoinFunction:process(types.bal:355)
ballerina.lang_query.0_0_1._InnerJoinFunction:process(types.bal:361)
........
The query works without the join clause, so there is something wrong with the join.
What could be the problem? Is it the right way to join json or is there a better way to do it?
Edit: Example data to reproduce the error:
dcrs:
[
{
"CDCRID": "D1234567",
"VCSOURCES": "EXAMPLE SOURCE",
"VCDATATYPS": "example",
"VCDATATYPL": "example",
"VCTARGETS": "EXAMPLE TARGET",
"VCDESCL": "Lorem ipsum dolor sit amet"
},
{
"CDCRID": "D3456789",
"VCSOURCES": "EXAMPLE SOURCE 2",
"VCDATATYPS": "example2",
"VCDATATYPL": "example2",
"VCTARGETS": "EXAMPLE TARGET2",
"VCDESCL": "Lorem ipsum dolor sit amet2"
}
]
tras:
[
{
"CTRAID": "T123456",
"DTIMEOUT": "2020-06-29T08:40:07.000+02:00",
"DTIMEIN": "2020-06-29T08:40:05.000+02:00",
"CDCRID": "D1234567"
},
{
"CTRAID": "T345678",
"DTIMEOUT": "2020-06-29T08:40:07.000+02:00",
"DTIMEIN": "2020-06-29T08:40:05.000+02:00",
"CDCRID": "D3456789"
}
]
Upvotes: 2
Views: 224
Reputation: 170
I have tried this within a function initializing json values within the function body. Here, you can do this simply with join
and from
clauses.
import ballerina/io;
public function main() returns error? {
json dcrs = [
{
"CDCRID": "D1234567",
"VCSOURCES": "EXAMPLE SOURCE",
"VCDATATYPS": "example",
"VCDATATYPL": "example",
"VCTARGETS": "EXAMPLE TARGET",
"VCDESCL": "Lorem ipsum dolor sit amet"
},
{
"CDCRID": "D3456789",
"VCSOURCES": "EXAMPLE SOURCE 2",
"VCDATATYPS": "example2",
"VCDATATYPL": "example2",
"VCTARGETS": "EXAMPLE TARGET2",
"VCDESCL": "Lorem ipsum dolor sit amet2"
}
];
json tras = [
{
"CTRAID": "T123456",
"DTIMEOUT": "2020-06-29T08:40:07.000+02:00",
"DTIMEIN": "2020-06-29T08:40:05.000+02:00",
"CDCRID": "D1234567"
},
{
"CTRAID": "T345678",
"DTIMEOUT": "2020-06-29T08:40:07.000+02:00",
"DTIMEIN": "2020-06-29T08:40:05.000+02:00",
"CDCRID": "D3456789"
}
];
json[] output = from var dcr in <json[]>dcrs
join var tra in <json[]>tras on dcr.CDCRID equals tra.CDCRID
select {
id: check dcr.CDCRID,
'source: check dcr.VCSOURCES,
target: check dcr.VCTARGETS,
transactionId: check tra.CTRAID
};
io:println(output);
}
Here, one thing to note is since source
is a reserved keyword in Ballerina Swan Lake, we have to use 'source
(with escape)
My output looks like the following.
[{"id":"D1234567","source":"EXAMPLE SOURCE","target":"EXAMPLE TARGET","transactionId":"T123456"},{"id":"D3456789","source":"EXAMPLE SOURCE 2","target":"EXAMPLE TARGET2","transactionId":"T345678"}]
Side note: Please check the latest way of defining resource functions with the Ballerina Swan Lake's latest syntax. (https://ballerina.io/learn/by-example/resource-methods/)
Here is an example you can refer.
Upvotes: 0