Appcelerator Blog

The Leading Resource for All Things Mobile

Node.ACS Integration Abstraction: Moving from MySQL to CouchDB

0 Flares 0 Flares ×

Mobile middleware provides a means of abstracting data integration between the mobile device and back end data sources. There are many benefits to this integration abstraction such as exposing a complex SOAP web service as a common REST API, which is more easily consumed by modern mobile devices. Another benefit is to insulate the mobile app from back end API changes. By implementing the integration in the mobile middleware tier, back end changes can be made without modifying the mobile application and going through lengthy application store approval processes and lengthy test cycles.

In a prior blog post, titled “Creating a MySQL-powered Web Service using Node.ACS”, I described how Appcelerator’s Node.ACS could be used to implement a cross device mobile middle tier for a MySQL based application. In this blog post, I will describe how to modify the Node.ACS service to retrieve the application data from CouchDB instead of MySQL without requiring any changes to the mobile app. This is illustrated in the diagram below.

The key to achieving this is to make sure that the CouchDB data exposed to the mobile app is in the format that the mobile app expects. The Node.ACS service will map the data returned from CouchDB to the same JSON format as the MySQL data was returned.

While this blog post describes a change in back ends from MySQL to CouchDB, the principles apply to any back end changes that would cause the mobile application to need to be redeployed, such as a change in web service syntax.

Review the existing application and Node.ACS Service

As covered in the previous blog post, the existing deployed application receives its data from the Node.ACS service nodesqldashboard.services_getData() in the following JSON format:

{
    "data": [
        {
            "tid": 0,
            "region": "NE",
            "mtd": 40,
            "ytd": 85
        },
        {
            "tid": 1,
            "region": "SE",
            "mtd": 39,
            "ytd": 43
        },
        {
            "tid": 2,
            "region": "West",
            "mtd": 32,
            "ytd": 25
        },
        {
            "tid": 3,
            "region": "Central",
            "mtd": 52,
            "ytd": 61
        },
        {
            "tid": 4,
            "region": "Canada",
            "mtd": 35,
            "ytd": 71
        }
    ],
    "MTDTotal": 198,
    "YTDTotal": 285
}

The payload includes the data returned from the MySQL connector, “data”, as well as computed sums, “MTDTotal” and “YTDTotal”, which are computed by the Node.ACS service.

We will need to make sure that we convert the CouchDB returned data and construct it in the exact payload format above before sending to the mobile application.

Integrating to CouchDB

Integration to CouchDB is simple since CouchDB exposing its data as a REST API. In this example, the data resides in a CouchDB database called “sales” and is retrieved by a view called “all” as follows:

http://lbrenman.cloudant.com/sales/_design/all/_view/all

The data returned by the REST API call above is:

{
    "total_rows": 5,
    "offset": 0,
    "rows": [
        {
            "id": "1e0906620deae259f5bf91392c78bfe2",
            "key": null,
            "value": {
                "_id": "1e0906620deae259f5bf91392c78bfe2",
                "_rev": "5-218d4acb28add17561775387248f8e72",
                "region": "NE",
                "month": 25,
                "year": 27
            }
        },
        {
            "id": "1e0906620deae259f5bf91392c962bf6",
            "key": null,
            "value": {
                "_id": "1e0906620deae259f5bf91392c962bf6",
                "_rev": "2-8d68256c6a70d4a6aef54428603ed47c",
                "region": "West",
                "month": 12,
                "year": 75
            }
        },
        {
            "id": "2aa785b05300d4d8d16c6d28824b04ab",
            "key": null,
            "value": {
                "_id": "2aa785b05300d4d8d16c6d28824b04ab",
                "_rev": "2-d3e13c6973616571f7ca6a11862656dc",
                "region": "SE",
                "month": 50,
                "year": 100
            }
        },
        {
            "id": "47ce4bb23b58a5e8bbef9e5e9d2a1178",
            "key": null,
            "value": {
                "_id": "47ce4bb23b58a5e8bbef9e5e9d2a1178",
                "_rev": "2-ce70972aa5ab6383c85ed4ecf3535112",
                "region": "Central",
                "month": 80,
                "year": 40
            }
        },
        {
            "id": "47ce4bb23b58a5e8bbef9e5e9d31189c",
            "key": null,
            "value": {
                "_id": "47ce4bb23b58a5e8bbef9e5e9d31189c",
                "_rev": "1-dedf7ca3bf93b463480278f8f139ec79",
                "region": "Canada",
                "month": 35,
                "year": 71
            }
        }
    ]
}

The Node. ACS service is shown below:

function getData(req, res) {
	
	var request = require("request");
	request.get("http:///sales/_design/all/_view/all", function (error, response, body) {
	    if (!error && response.statusCode == 200) {
	        var resultsObj = JSON.parse(body);
	        
	        var results = [];
	        var reply = {};
		  	var rLen = resultsObj.rows.length;
		  	var MTDTotalVal = 0;
		  	var YTDTotalVal = 0;
 		  	
		  	if(rLen>0){
		  		for(var i=0;i<rLen;i++){
		  			MTDTotalVal += resultsObj.rows[i].value.month;
		  			YTDTotalVal += resultsObj.rows[i].value.year;
		  			results.push({tid:resultsObj.rows[i].id, region:resultsObj.rows[i].value.region, mtd:resultsObj.rows[i].value.month, ytd:resultsObj.rows[i].value.year});
		  		}
		  	}
		  	
		  	reply = {data: results, MTDTotal: MTDTotalVal, YTDTotal: YTDTotalVal};
		  		
		  	res.set('Content-Type', 'application/json');
		  	res.send(JSON.stringify(reply));
			res.end();
	        
	    } else {
	    		res.send('Error');
	    		res.end();
	    }
	});
};

The function getData() makes an HTTP request using the “request” Node Packaged Module (npm) for convenience and parses the response into the required format.

Once the Node.ACS service is redeployed (e.g. acs publish –force), the client mobile application does not need to be re-compiled, fully tested or re-deployed. It does not even need to be restarted.

In this blog post, we modified the back end integration to a mobile application without needing to rebuild or deploy a new mobile application. This was accomplished easily since the mobile application integration was implemented through the Appcelerator Node.ACS middleware tier. We simply modified the Node.ACS service to connect to CouchDB instead of MySQL and formatted the mobile payload to match the existing payload. This is a very powerful concept and should be employed for all mobile applications as it makes the mobile application lifecycle more manageable.

Project files can be found here.
0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- 0 Flares ×

1 Comment

Comments are closed.

Sign up for updates!

Become a mobile leader. Take the first step to scale mobile innovation throughout your enterprise.
Get in touch
computer and tablet showing Appcelerator software
Start free, grow from there.
0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- 0 Flares ×