Couchbase Functions
Here’s the Functions part. You set add this either through the Eventing panel of the Couchbase Server console, or via a REST call.[2]
function OnUpdate(doc, meta) {
if (doc.resourceType != 'Observation') return;
let reference = doc.subject.reference;
let url = "http://localhost:8080/events/" + reference.substr(9);
let data = JSON.stringify({
"reference": doc.subject.reference,
"code": doc.code.coding[0].code,
"recordedAt": doc.issued,
"value": doc.valueQuantity.value
});
let curl = SELECT CURL($url, {
"request": "POST",
"header": [ "Content-Type: application/json", "accept: application/json" ],
"data": $data
});
curl.execQuery();
}
function OnDelete(meta) {}
In the FHIR specification, documents all have a resourceType
. We only look at “Observation” resources, so the first check filters on that.
Next, we extract the UUID of the patient from the subject reference field. That gets used in routing on the web app server side. (See the next section for more on this.)
Then we create a JSON string with only the subject reference, a code indicating the type of observation made, the date this particular one was taken, and the measurement value. That’s the only data we need to pass.
Finally, we make use of the cURL capability in N1QL to POST that data to the app server REST endpoint.
Web Server REST Endpoint
The app server is written in Node using Express. We defined a route in Express to create the endpoint used in the cURL call in the Functions code.
router.post('/:id', function(req, res, next) {
res.send('');
if (sse[req.params.id] === undefined) return; // Not listening yet
sse[req.params.id](`event: update\ndata: { "values": [${JSON.stringify(req.body)}]}\n\n`);
});
module.exports = router;
Express let’s you define a portion of a route, and then hang it off of a longer path when wiring things together. Hence all you see here is the end part of the route specification. The :id
element tells Express to take the last segment of the URL and feed it to our callback as a parameter. Recall here we add the patient UUID as the last part of the URL path. So that’s what the id
parameter gets set to.
Having triggered this route with our cURL call, we need to get the information pushed out to the web client. We could have used web sockets. Instead, we chose to use server-sent events. SSEs are lighter weight than web sockets, and work well for this purpose. We’ll go into SSEs further in another post. For now, just think of it as a message channel that uses a very simple format.
That gives us what we need to know to understand the callback code. The first line specifies the route. The second line sends an empty response, to close out the cURL session. Next we check whether the server-sent events channel has been set up yet. This happens via a call from the client. If the SSE channel is ready, we tag our data as an “update” event, and send out the same JSON we received.