This post focuses on invoking secured Fusion Cloud RESTFul services using Node.js. Part 1 is explicitly focused on the "GET" method. The assumption is that the reader has some basic knowledge on Node.js. Please refer to this link to download and install Node.js in your environment.
Node.js is a programming platform that allows you to execute server-side code that is similar to JavaScript in the browser. It enables real-time, two-way connections in web applications with push capability, allowing a non-blocking, event-driven I/O paradigm. It runs on a single threaded event loop and leverages asynchronous calls for various operations such as I/O. This is an evolution from stateless-web based on the stateless request-response paradigm. For example, when a request is sent to invoke a service such as REST or a database query, Node.js will continue serving the new requests. When a response comes back, it will jump back to the respective requestor. Node.js is lightweight and provides a high level of concurrency. However, it is not suitable for CPU intensive operations as it is single threaded.
Node.js is built on an event-driven, asynchronous model. The in-coming requests are non-blocking. Each request is passed off to an asynchronous callback handler. This frees up the main thread to respond to more requests.
An internet media type data for RESTFul services is often JavaScript Object Notation (JSON). JSON is a lightweight data-interchange format and it is a standard way to exchange data with RESTFul services. It is not only human readable, but easy for machines to parse and generate. For more information on JSON, please refer to this link.
Var Employee = { “name” : “Joe Smith” “ID” : “1234” “email” : joe.smith@oracle.com };
var emailGroups = [{ "email" : "email1@myCompany.com", "name" : "Joe Smith" }, { "email" : " email2@myCompany.com ", "name" : "Don Smith" }];
The RESTFul services in Oracle Fusion Cloud are protected with Oracle Web Service Manager (OWSM). The server policy allows the following client authentication types:
The client must provide one of the above policies in the security headers of the invocation call for authentication. The sample in this post is using HTTP Basic Authentication over SSL policy.
In general there are two modules to invoke HTTP/s secured REST services for GET method:
This native API implicitly calls http.request set to GET and calls request.end() automatically. There are two parameters for this method that defines what and how the REST services is being invoked. The following snippet demonstrates the construct for HTTP/s invocation:
var client = require('https') request = client.get(options, function(response) {…}
The above command uses HTTPS protocol. The “require” statement enables either HTTP or HTTPS protocol.
The "options" is an object or string that includes the following information:
For more information on object "options", refer the following link.
This a typical example of constructing 'option'
var options = { ca: fs.readFileSync('myCert'), host: 'hostname.mycompany.com', port: 443, path: '/hcmCoreApi/atomservlet/employee/newhire', headers: { 'Authorization': 'Basic ' + new Buffer(uname + ':' + pword).toString('base64') }
This is a callback parameter as a one time listener for the response event. It is emitted when a response is received to this request.
To get the response, add a listener for 'response' to the request object. The 'response' will be emitted from the request object when the response headers have been received. The 'response' event is executed with one argument which is an instance of http.IncomingMessage.
During the 'response' event, one can add listeners to the response object; particularly to listen for the 'data' event.
If no 'response' handler is added, then the response will be entirely discarded. However, if you add a 'response' event handler, then you must consume the data from the response object, either by calling response.read() whenever there is a 'readable' event, or by adding a 'data' handler, or by calling the .resume() method. Until the data is consumed, the 'end' event will not fire. Also, until the data is read it will consume memory that can eventually lead to a 'process out of memory' error.
Note: Node does not check whether Content-Length and the length of the body which has been transmitted are equal or not.
The following sample has implemented three events:
request = http.get(options, function(res){ var body = ""; res.on('data', function(chunk) { body += chunk; }); res.on('end', function() { console.log(body); }) res.on('error', function(e) { console.log("Got error: " + e.message); }); });
The request module is designed to make various HTTP/s calls such as GET, POST, PUT, DELETE, etc. The http.get() implicitly calls http.request set to GET and calls request.end() automatically. The code for GET method is identical to http.get() except for the following:
var options = { ca: fs.readFileSync('myCert'), host: 'hostname.mycompany.com', port: 443, method: GET, path: '/<fusion_apps_api>/employee', headers: { 'Authorization': 'Basic ' + new Buffer(uname + ':' + pword).toString('base64') } var request = http.request(options, function(res){…} …. request.end();
The HTTP status code is available from response event function function(res). For example
res.statusCode
The HTTP response headers are available from same response event function as follows:
res.headers
The response JSON message can be parsed using JSON object. The JSON.parse() parses a string from the RESTFul services. For example:
JSON.parse(responseString)
var uname = 'username'; var pword = 'password'; var http = require('https'), fs = require('fs'); var options = { ca: fs.readFileSync('MyCert'), host: 'host.mycompany.com', port: 10620, path: '/<fusion_apps_api>/employee', headers: { 'Authorization': 'Basic ' + new Buffer(uname + ':' + pword).toString('base64') } }; request = http.get(options, function(res){ var responseString = ""; res.on('data', function(data) {
responseString += data;
}); res.on('end', function() { console.log(responseString);
}) res.on('error', function(e) { console.log("Got error: " + e.message); }); });
var uname = 'username'; var pword = 'password'; var http = require('https'), fs = require('fs'); var options = { ca: fs.readFileSync('hcmcert1'), host: 'host.mycompany.com', port: 10620, path: '/<fusion_apps_api>/employee', method: 'GET', headers: { 'Authorization': 'Basic ' + new Buffer(uname + ':' + pword).toString('base64') } }; var request = http.request(options, function(res){ console.log(res.headers); var responseString = ''; res.on('data', function(chunk) { console.log(chunk); responseString += chunk; }); res.on('end', function() { console.log(responseString); }) res.on('error', function(e) { console.log("Got error: " + e.message); }); }); request.end();
This post demonstrates how to invoke secured Fusion Cloud REST Services using Node.js. It also provides basic introduction to JSON format and how to parse the JSON response in Node.js. The sample code is a prototype and must be further modularized for re-usability.
A product strategist and “solution and enterprise” integration architect to innovate and automate complex integration patterns with Oracle SaaS applications.
Next Post