Connecting to external REST API (complete example)
Hi,
In the last several days, I was able to integrate the ICD 11 coding tool, which is based on a REST API using OAUTH2 authentication, into my EMR Ninox database.
There is no complete example in the Ninox community demonstrating the steps needed to connect with an external API for novel users like me, so I decided to share my ICD 11 API module.
It is a simplified version (without global functions or extended log files) but functional and tested. All the code runs inside a 'trigger after update' text field. The only thing you have to do is to obtain your "client id" and "client secret" by registering here (it's free) and copy them to the corresponding fields of the 'configICD-11' table. Then go to the 'Search' table, type in a keyword like "hypertension" into the 'Search ICD-11' field, and press enter. See the code below:
'Select code' := null;
'Error message' := "";
(select tempResults).(
Code := null;
Title := null
);
let tokenEndpoint := "https://icdaccessmanagement.who.int/connect/token";
let linearizationEndpoint := "https://id.who.int/icd/release/11/2023-01/mms/search?q=" + 'Search ICD-11' +
"%25&subtreeFilterUsesFoundationDescendants=false&includeKeywordResult=false&useFlexisearch=false&flatResults=true&highlightingEnabled=false&medicalCodingMode=true";
let clientId := first((select 'configICD-11')[Key = "client_id"]).Value;
let clientSecret := first((select 'configICD-11')[Key = "client_secret"]).Value;
let body := "client_id=" + clientId + "&client_secret=" + clientSecret +
"&scope=icdapi_access&grant_type=client_credentials";
let headers := {
'Content-Type': "application/x-www-form-urlencoded",
'Content-Lenght': length(body)
};
let accessToken := first((select 'configICD-11')[Key = "access_token"]);
let tokenTimestamp := first((select 'configICD-11')[Key = "token_timestamp"]);
let remainSec := 0;
if tokenTimestamp.Value != null then
let tokenAge := now() - datetime(number(tokenTimestamp.Value));
remainSec := (3600000 - number(tokenAge)) / 1000
end;
if remainSec < 500 then
let response := do as server
http("POST", tokenEndpoint, headers, body)
end;
if response.error then
'Error message' := text(response.error)
else
tokenTimestamp.(Value := text(number(now())));
let json := parseJSON(text(response.result));
accessToken.(Value := text(json.token_type) + " " + text(json.access_token))
end
end;
headers := {
Authorization: accessToken.Value,
Accept: "application/json",
'API-Version': "v2",
'Accept-Language': "en"
};
let response := do as server
http("GET", linearizationEndpoint, headers, null)
end;
if response.error then
'Error message' := text(response.error)
else
let i := 1;
for item in response.result.destinationEntities do
record(tempResults,i).(
Code := text(item.theCode);
Title := text(item.title)
);
i := i + 1
end
end
I would only achieve the above with the help of and . If you want to dive into all the fantastic code they share, visit this post: https://forum.ninox.com/t/h7hv5kf/integration-of-the-icd-11-coding-tool-into-a-ninox-database
Many thanks. You are incredible!
PS. If you find any bugs, please don't hesitate to let me know.
6 replies
-
.. Glad it was useful. Hopefully you also picked up on the "getAccessToken" global function in the other database. Most auth tokens have an expiry time limit.. So.. if you are making numerous API calls .. you do not need to get a new token unless the one you have has "expired"
And.. Jacques is a JavaScript guru!
Good luck.. Thank you for sharing your example.. I hope it works out for you! -
OK.. I saw your logic in the trigger.. ;)
-
I'm sorry, but I backed up the database without data... I am attaching the correct archive!
-
Thanks to the specialists (Mike and Jacques) for jumping in, it pleases me to see everyone trying to help solve problems and sharing their ideas with each other!!
Big thanks!
Content aside
-
3
Likes
- 1 yr agoLast active
- 6Replies
- 494Views
-
4
Following