Code Explanation - Multitenancy

A basic SOAJS service is made up of two files:

  • config.js: Contains the metadata of the service (name, port, etc...), in addition to that of each of the APIs alongside its corresponding parameters.
  • index.js: Contains the definitions of the APIs, that is their respective implementation.

The below snippets represent the content of both index.js and config.js that represent the MultiTenancy Service (example 03).

The code of MultiTenancy Service resembles that of the Basic SOAJS Service. However, in this example, extKeyRequired property is set to true is used.

This property and its uses is explained in details in the code snippets below.

Below each snippet is a small explanation of how each of them works.

config.js
'use strict';
/**
 * @license
 * Copyright SOAJS All Rights Reserved.
 *
 * Use of this source code is governed by an Apache license that can be
 * found in the LICENSE file at the root of this repository
 */

module.exports = {
	"type": 'service',
	"prerequisites": {
		"cpu": '',
		"memory": ''
	},
	"serviceVersion": 1,
	"serviceName": "example03",
	"serviceGroup": "SOAJS Example Service",
	"requestTimeout": 30,
	"requestTimeoutRenewal": 5,
	"servicePort": 4023,
	"extKeyRequired": true,
	"oauth": true,
	
	"errors": {},
	"schema": {
		"commonFields": {
			"firstName": {
				"source": ['query.firstName'],
				"required": true,
				"default": "John",
				"validation": {
					"type": "string"
				}
			},
			"lastName": {
				"source": ['query.lastName'],
				"required": true,
				"validation": {
					"type": "string"
				}
			}
		},
		"get": {
			"/testGet": {
				"_apiInfo": {
					"l": "Test Get",
					"group": "Example"
				},
				"commonFields": ["firstName", "lastName"]
			},
			"/buildName": {
				"_apiInfo": {
					"l": "Build Name",
					"group": "Example"
				},
				"commonFields": ["firstName", "lastName"]
			}
		}
	}
};

The service configuration of this example has an extra property that didn't exist in the previous examples. Indeed, the extKeyProperty notifies the service that it is a multitenant service.

Therefore, users requesting the usage of the service APIs must be logged in, and provide a valid authentication key. The authentication key serves as an ID of the user. This ID

is used by the service in order to check the users' permission in order to determine the ability to use a service's API.

config.js
'use strict';
/**
 * @license
 * Copyright SOAJS All Rights Reserved.
 *
 * Use of this source code is governed by an Apache license that can be
 * found in the LICENSE file at the root of this repository
 */

const soajs = require('soajs');
const config = require('./config.js');

let service = new soajs.server.service(config);

service.init(function () {
	service.get("/testGet", function (req, res) {
		res.json(req.soajs.buildResponse(null, {
			firstName: req.soajs.inputmaskData.firstName,
			lastName: req.soajs.inputmaskData.lastName
		}));
	});
	
	service.get("/buildName", function (req, res) {
		let tenant = '';
		if (req.soajs.servicesConfig) {
			if (req.soajs.servicesConfig.example03) {
				if (req.soajs.servicesConfig.example03.tenantName) {
					tenant = req.soajs.servicesConfig.example03.tenantName;
				}
			}
		}
		let name = req.soajs.inputmaskData.firstName + ' ' + req.soajs.inputmaskData.lastName;
		res.json(req.soajs.buildResponse(null, {
			tenantName: tenant,
			fullName: name
		}));
	});
	
	service.start();
});

The index.js file implements the two APIs of the service.

The "testGet" API simply returns the first name and the last name sent by the query.

The "buildName" API, on the other returns the tenant name and the fullName sent by the query.

Note that the tenant name is extracted from the req.soajs.servicesConfig which contains information specific to the user logged in to the service.