Code Explanation - Basic Service

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 implementation of the APIs.

When a request arrives at the service, the IMFV maps, validates, and formats all arriving input parameter, before consolidating them all into one object.

After the IMFV checks for the validity of the supplied input parameters, ensures the existence of all the required parameters, the request is forwarded to the API.

You can learn more on the functionality of the IMFV by visiting the IMFV section.


The below snippets represent the content of both index.js and config.js that represent the Basic SOAJS service (example 01).

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": "example01",
	"serviceGroup": "SOAJS Example Service",
	"requestTimeout": 30,
	"requestTimeoutRenewal": 5,
	"servicePort": 4010,
	
	"extKeyRequired": false,
	"oauth": false,
	
	"errors": {
		"900": "firstName not found"
	},
	"schema": {
		"get": {
			"/testGet": {
				"_apiInfo": {
					"l": "Test Get",
					"group": "Example"
				},
				"firstName": {
					"source": ['query.firstName'],
					"required": true,
					"validation": {
						"type": "string"
					}
				},
				"lastName": {
					"source": ['query.lastName'],
					"required": true,
					"validation": {
						"type": "string"
					}
				},
				"email": {
					"source": ['query.email'],
					"required": false,
					"validation": {
						"type": "string",
						"format": "email"
					}
				}
			},
			"/buildName": {
				"_apiInfo": {
					"l": "Build Name",
					"group": "Example"
				},
				"firstName": {
					"source": ['query.firstName'],
					"required": true,
					"default": "John",
					"validation": {
						"type": "string"
					}
				},
				"lastName": {
					"source": ['query.lastName'],
					"required": true,
					"validation": {
						"type": "string"
					}
				}
			}
		},
		"delete": {
			"/testDel": {
				"_apiInfo": {
					"l": "Test Delete",
					"group": "Example"
				},
				"firstName": {
					"source": ['query.firstName'],
					"required": false,
					"validation": {
						"type": "string"
					}
				},
				"lastName": {
					"source": ['query.lastName'],
					"required": false,
					"validation": {
						"type": "string"
					}
				}
			}
		},
		"post": {
			"/testPost": {
				"_apiInfo": {
					"l": "Test Post",
					"group": "Example"
				},
				"firstName": {
					"source": ['body.firstName'],
					"required": true,
					"validation": {
						"type": "string"
					}
				},
				"lastName": {
					"source": ['body.lastName'],
					"required": true,
					"validation": {
						"type": "string"
					}
				},
				"email": {
					"source": ['body.email'],
					"required": false,
					"validation": {
						"type": "string",
						"format": "email"
					}
				}
			}
		},
		"put": {
			"/testPut": {
				"_apiInfo": {
					"l": "Test Put",
					"group": "Example"
				},
				"firstName": {
					"source": ['body.firstName'],
					"required": true,
					"validation": {
						"type": "string"
					}
				},
				"lastName": {
					"source": ['body.lastName'],
					"required": true,
					"validation": {
						"type": "string"
					}
				},
				"email": {
					"source": ['body.email'],
					"required": false,
					"validation": {
						"type": "string",
						"format": "email"
					}
				}
			}
		}
	}
};

As we mentioned above, the "config.js" contains all the metadata of the service, including its APIs.

In the sample above, there exists information about the service: its name, the port it listens to, the errors, and finally a schema containing the APIs.

Let us analyze the "testGet" API:

Each API is referenced by a label, which is, in this case, "Test Get", under the "_apiInfo" JSON object.

This API expects three input parameters (firstName, lastName, and email) of type String.

These parameters are supplied through the query (i.e. the URL passed in the browser).

More information related to the IMFV can be found under the IMFV section in the documentation.

In this example, the firstName, and lastName are required, whereas the email is not.

Similar to the explained API, the user must add in the schema all the needed APIs, along with any additional information needed.

index.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,
			email: req.soajs.inputmaskData.email
		}));
	});
	
	service.get("/buildName", function (req, res) {
		//write your business logic here
		let fullName = req.soajs.inputmaskData.firstName + ' ' + req.soajs.inputmaskData.lastName;
		res.json(req.soajs.buildResponse(null, {
			fullName: fullName
		}));
	});
	
	service.delete("/testDel", function (req, res) {
		// some business logic
		res.json(req.soajs.buildResponse(null, true));
	});
	
	service.post("/testPost", function (req, res) {
		if (req.soajs.inputmaskData.firstName !== 'John') {
			//EXAMPLE: to simulate error response return
			res.json(req.soajs.buildResponse({"code": 900, "msg": config.errors[900]}));
		} else {
			res.json(req.soajs.buildResponse(null, {
				firstName: req.soajs.inputmaskData.firstName,
				lastName: req.soajs.inputmaskData.lastName,
				email: req.soajs.inputmaskData.email
			}));
		}
	});
	
	service.put("/testPut", function (req, res) {
		res.json(req.soajs.buildResponse(null, {
			firstName: req.soajs.inputmaskData.firstName,
			lastName: req.soajs.inputmaskData.lastName
		}));
	});
	
	service.start();
});

The sample above contains the implementation of each of the five APIs that form the service.

Consider the first API "testGet", which uses the GET method. 

The API generates a JSON response containing the firstName, lastName, and email, obtained from the request.

Another example to consider is the "testPost" API, which uses the POST method.

The API evaluates the firstName parameter. If not equal to "John", it replies with error code 900, which is also defined in the config.js file.

However, if the firstName is equal to "John", the API generates a JSON response containing the firstName, lastName, and email, obtained from the request.