01 - Service

Introduction


The following is an example of a microservice that uses the composer to function.

This service makes use of model injection and as such, we adhere to this folder schema to maintain code standardization.


Note

For the sake of this example, create a database called "company" and a collection inside it called "employees

Folder Schema


 


Code Samples


config.js
"use strict";

module.exports = {
   "type": "service",	//differentiator between service and daemon
   "dbs": [				//tells the composer which dbs to the service or daemon are using
      {
         prefix: "",
         name: "company",
         mongo: true,
         multitenant: false
      }
   ],
   
   "prerequisites": {		//required for High availability mode
      "cpu": '',
      "memory": ''
   },
   "serviceName": "composerService",	//name of the service
   "serviceGroup": "Composer",			//name of the service group
   "serviceVersion": 1,					//version of the service
   "servicePort": 4200,					//port where the service will listen
   "requestTimeout": 30,				//time in ms to timeout for a request
   "requestTimeoutRenewal": 5,			//max number of requests to attempt before returning an error
   "extKeyRequired": false,				//set to true if service is multitenant
   "session": false,					//set to true if service requires session
   "oauth": false,						//set to true is service is secured by oauth
   "injection": true,					//set to true if model injection is supported
   "errors": {							//object that contains all the errors that the service can throw
      400: "Error connecting to database"
   },
   "models": {
      "path": __dirname + "/lib/model/",	//location of model files
      "name": "mongo"
   },
   "schema": {
      "commonFields": {		//common imfv fields used by the routes
         "name": {
            "source": ['body.name'],
            "required": true,
            "validation": {"type": "string"}
         },
         "id": {
            "source": ['body.id'],
            "required": true,
            "validation": {"type": "number"}
         },
         "position": {
            "source": ['body.position'],
            "required": true,
            "validation": {"type": "string"}
         }
      },
      "post": {		//must sort APIs by method
         "/add": {		//route name
            "_apiInfo": {
               "l": "Adds record to database",
               "group": "Add"
            },
            "mw": __dirname + "/lib/mw/add.js",		//middleware file containing API business logic
            "imfv": {								//imfv used by API
               "commonFields": ["name", "id", "position"]
            }
         }
      }
   }
};


index.js
"use strict";
var composer = require("soajs.composer");
//require the composer

composer.deploy(__dirname + "/config.js", function(error){
//call the deply function to start the service from the provided config file

   console.log( (error)? error : "Composer Service started ...");
	//return an error if one is thrown
});


Middleware:

add.js
"use strict";

var states = {
   
   "mw": function (req, res, next) {
      
      var combo = {
         //extract the required information from the request
         "record": {
            "name": req.soajs.inputmaskData.name,
            "employeeId": req.soajs.inputmaskData.id,
            "employeePosition": req.soajs.inputmaskData.position
         }
      };
            
      req.soajs.model.insertEntries(req.soajs, combo, function (error) {
		//use the model to insert the record into the database

         if (error) {
            return res.soajs.returnAPIResponse(req, res, {"code": 400, "error": error});
         }
         
         return res.soajs.returnAPIResponse(req, res, {"code": 400, "error": error, data: "Insert Successful"});
         
         
      });
      
      
   }
};

module.exports = states;

Model:

mongo.js
"use strict";
var database = 'company';
var collection = 'employees';

var lib = {
   "defaults": function (combo) {
	//formulate the input parameters that the insert command in mongo expects
      if (!combo.database) {
         combo.database = database
      }
      if (!combo.collection) {
         combo.collection = collection
      }
      if (!Object.hasOwnProperty.call(combo, 'versioning')) {
         combo.versioning = false;
      }
   },
   
   "insertEntries": function (soajs, combo, cb) {
      lib.defaults(combo);     
      soajs.mongo[combo.database].insert(combo.collection, combo.record, (combo.versioning || false), cb);
      
   }
};

module.exports = lib;


How to test


You can test this service for yourself by doing the following:

  • Create a local version of the folder schema on your machine
  • Copy the code from this page into their respective files
  • Run the following commands from a terminal window


Start controller
# go to the controller directory and start the controller in the correct environment


cd /opt/soajs/node_modules/soajs.controller


export SOAJS_ENV=dev
export SOAJS_SRVIP = 127.0.0.1


node .
  • IN A NEW TERMINAL WINDOW:
Start service
# go to the service directory and start the service in the correct environment


cd /opt/soajs/node_modules/composer.example/service


export SOAJS_ENV=dev
export SOAJS_SRVIP = 127.0.0.1

node .