Service

Building a service with SOAJS is straight forward.

Create your service next to the node_modules directory that was created when installing core:

mkdir /opt/soajs/myService

Now create 2 files within that directory:

  • index.js used to write the code of the service APIs
  • config.js used for IMFV and custom service configuration

Basic Example


The following code snippet shows how to write a service with SOAJS that has one route using the GET protocol. The service reads 2 inputs from the query string of the request, puts them in a JSON object and returns the object in the response. This code is found in the index.js of a service that you created in the above step.
The second file config.js, contains the service information such as name and the port number the service will run on.

index.js
'use strict';		// "strict mode" in JavaScript
var soajs = require('soajs');	// require soajs framework
var config = require('./config.js');	// require local configuration file
var service = new soajs.server.service(config);		// create a service using SOAJS
service.init(function() {		// initialize the service
    service.get("/hello", function(req, res) {		//create API "/hello" that uses GET method and pass "request" and "response" to API
        var name = req.soajs.inputmaskData.firstName + " " + req.soajs.inputmaskData.lastName;	//create variable "name" that formulates a string from received inputs
        res.json(req.soajs.buildResponse(null, "Hello " + name));		// API returns a JSON response using SOAJS buildResponse
    });
    service.start();		// start the service
});
config.js
'use strict';		// "strict mode" in JavaScript
module.exports = {		// export the JSON object when this file is required
    "serviceVersion": 1,		// specify the service version
    "serviceName": "helloworld",		//specify the service name
    "serviceGroup": "SOAJS Example Services",		//specify the service group
    "servicePort": 4020,		// specify the service port
    "requestTimeout": 30,		// specify how long (in seconds) to wait for a response before a request to the service api times out
    "requestTimeoutRenewal": 5,		// specify the number of attempts, in case of a timeout, before considering the service api unreachable
    "awareness": true,		//  if the awareness is enabled, the service becomes aware of the controller's location
    "extKeyRequired": false,	// specify if the service is multitenant or not
    "oauth": false,		// specify if the service should be protected by oAuth
    "errors": { "400": "please provide a firstName and a lastName" },		// Object containing the error codes of this service
    "schema": {		// Object containing service APIs schema
        "/hello": {		// First API whose route value is /hello
            "_apiInfo":{ "l": "hello world" },		//API Information containing the label representation; displayed in Dashboard UI
            "firstName": { "source": ["query.firstName"], "required": true, "validation": {"type": "string"}},	//  API parameters firstName and lastName used by IMFV
            "lastName": { "source": ["query.lastName"], "required": true, "validation": {"type": "string"}}
        }
    }
};

Configuration Options


Property NameDescriptionDefault Value
extKeyRequiredsoajs evolves the service and makes it multitenant supportive.
- The service thus can be used by multiple tenants and is only accessible when a tenant key is provided 
- Key security is turned on; device and geo information can be configured 
- If configured, SOAJS will also be able to compare the access to the requested service APIs
FALSE
uracif set to true, you will get access to the user information without his profile, ACL and provision → Available syntax: req.soajs.urac;FALSE
urac_Profileif set to true and urac is set to true, you will get access to get the profile of the logged in user → Available syntax: req.soajs.urac;FALSE
urac_ACLif set to true and urac is set to true, you will get access to get the ACL of the logged in user Available syntax: req.soajs.urac;FALSE
provision_ACLif set to true and urac is set to true, you will get access to get the package and tenant ACL Available syntax: req.soajs.tenant.application.package_acl; req.soajs.tenant.application.package_acl_all_env;FALSE
sessionIf set to true, SOAJS creates a persistent session and adds it to the request object.FALSE
oauthif set to true, the service becomes protected by oauth. Only requests that have a valid access_token are permitted to use the APIs of this service. FALSE
bodyParsersoajs parses the body to json allowing it to extend it and add its functionality and data to it.TRUE
methodOverridesoajs provides the ability to use PUT and DELETE in HTTP requests where the request doesn't support it by default.TRUE
cookieParsersoajs parses cookies from the request consolidates them under one object "cookies" and attaches them to the request object.TRUE
loggersoajs gives you the ability to have unified and standardized api logging (error, debug, info, …). With the power of soajs.agent, the unified logging will be fed into elastic search and the soajs.dashboard.ui to give you amazing analytic information.TRUE
inputmasksoajs makes it easy by consolidating all the api params from multiple source(post, get, cookie, headers, session, provisioning, …) under one object after formatting and validation. TRUE

Note

Notice that bodyParser, methodOverride, cookieParser, logger and inputmask are not added to the configuration. By default, these properties are set to TRUE if not provided. To disabled their usage, add them to the object declaration and set their values to FALSE.

Starting the Service


Every service created with SOAJS is implemented using NodeJs therefore start the service using node in a terminal:

> cd /opt/soajs/myService/
> node index

Your service will run and will be listening on the port specified in config.js which in this case is 4020. Your service will also be listening on a second port used for maintenance purposes. That port is equal to the default port specified in config.js + 1000 and in this case has the value of 5020. Once your service is running, make a call via CURL like the following:

curl -X GET "http://127.0.0.1:4020/hello?firstName=John&lastName=Doe"

Calling the Service


Now that the service is running, we will make 3 calls:

  1. Heartbeat: test that the service is healthy.
  2. Default Port: make a call to the service without specifying any API.
  3. Call Service API: call the API of the service and pass the parameters to it.

As mentioned in the above section, a maintenance port is used to perform maintenance operations such as checking if a service is healthy which in this case it's called "heartbeat".

curl -X GET "http://127.0.0.1:5020/heartbeat"
Response
{
    "result":true,
    "ts":1425054123486,
    "service": {
        "service":"HELLOWORLD",
        "type":"rest",
        "route":"/heartbeat"
    }
}


Now let's call the service by running the following curl command:

curl -X GET "http://127.0.0.1:4020"
Response
{
    "result":false,
    "errors": {
        "codes": [ 151 ],
        "details": [
            {
                "code": 151,
                "message": "You are trying to reach an unknown rest service!"
            }
        ]
    }
}

Here we attempted to call the service without specifying its API. The returned response was a fail because basically there is no point in calling a service without asking for any of its APIs.


Let's try to call the API in our service by running this curl command:

curl -X GET "http://127.0.0.1:4020/hello?firstName=John&lastName=Doe"
Response
{
    "result": true,
    "data": "Hello John Doe"
}

This time the API returned a valid response with the JSON Object containing all the parameters we specified.


Checkout Get Started section along with the examples it offers to learn how to create basic services, protect them, make them multitenant and benefit from the tons of features SOAJS offers.