Accessing Bluemix Services from Client-side Web Applications

Bluemix is IBM’s cloud platform to build and host applications which can leverage more than 100 services, for example databases and cognitive services. The services provide APIs which require credentials. Applications which are hosted on Bluemix as Cloud Foundry apps or Docker containers can access these credentials from environment variables. This article describes how to invoke Bluemix services from client-side web applications.

Recently I described how to deploy Angular and other client-side web applications (for example React or Vue.js) to Bluemix via Docker and nginx. In order to allow web applications to invoke REST APIs, nginx acts as a proxy which can be configured in the nginx.conf file.

I couldn’t figure out how to configure/extend the nginx proxy to access the credentials from environment variables. That’s why I replaced nginx with a web server built with Node.js and the Express framework.

There are various proxy server implementations for Express available or you can write a simple proxy yourself. The following code shows a proxy for get requests which reads credentials of the Watson Conversation service and adds them to the request.

router.get('*', (req, res) => {
  var vcapCredentials = readCredentials();
  var credentials = req.get('Authorization');
  if (vcapCredentials.username && vcapCredentials.password) {
    credentials = "Basic " + new Buffer(vcapCredentials.username + ':' + vcapCredentials.password).toString('base64');
  var url = '' + req.url;
  var newRequest = request.get({
    uri: url,
    headers: {
      'Content-Type': 'application/json',
      'Authorization': credentials

The full source code of the sample application is available on GitHub.

The screenshot shows the requests from the web application to the Node.js backend. With ‘/credentials‘ the web application checks whether the credentials exist which is the case when a Watson Conversation service has been bound to the Node.js application. If they exist, the two input fields for username and password are disabled. The ‘/conversation/api/v1/workspaces‘ request invokes the proxy.