Monday, March 28, 2011

Partly Cloudy - Node.js and the IFS

With Node.js surfing the hype wave, we have received some requests from our clients on how to use Node.js to poll the IFS web services.

This is actually a good idea ... let me add another buzz word to explain why: SEO.

In the following scenario we'll make Node.js call the casa.keru search service from the Tredix IFS and serve the results as HTML to the browser. The result will be a static web page listing some properties for sale.

It is very important to understand the difference between a static and a dynamic web page. In most of our other examples (including the casa.keru.pt web application itself), we are calling the IFS web services from within the browser. This technology is commonly known as AJAX; the DOM is manipulated on the fly. AJAX is really cool and fun to use, because all the magic happens dynamically within your page without any page reloads. However, in SEO terms, AJAX is not helpful at all. When the Google bot stops by, it can only index the static content of our page (which is usually not much more than a HTML wrapper) - but not the dynamically generated content. However, this is where the beef is.

So the good old fashioned static web page can still be desirable, especially in terms of SEO. With Node.js, there's no need to write a server side program in yet another language such as PHP, Python, Ruby or ASP.NET/C#. Instead, JavaScript developers can use their client-side JavaScript skills to let rip on the server.

Plus: It's incredibly simple! Check out the basic example below which sets up a web server on 127.0.0.1:8124, calls the IFS search service, and delivers a static list of properties to the browser. Each time you hit refresh, you'll skip to the next page of property listings. The code is pretty self-explanatory and should allow for an instant start - enjoy!

// tested on Node.js 0.4.x

var http=require('http');

var GroupID='PT-08_ABF_01'; // Freguesia Albufeira
var counter=0, html="";

http.createServer(function (req, nodeResponse) {

  // Ignore browser requests for Favicon
  // console.log(req.url);
  if (req.url=="/favicon.ico") return false;

  counter++;
  var options = {
    host: 'arrakis.tredix.com',
    method: 'GET',
    port: 59180,
    path: '/apache-tomcat/Tredix/ISS?Context=Tredix/IFS/ImmoPT/ProtoTyp2/Search&ContentType=json'+
    '&BusinessType=SALE' +
    // '&PropertyType=' +
    '&MinPrice=0' +
    '&MaxPrice=0' +
    '&NumberOfBedrooms=' +
    '&Language=PT' +
    '&IncludeObjectsWithPriceOnApplication=true' +
    '&IncludeBoundaries=false' +
    '&IncludeMisses=false' +
    '&Currency=EUR' +
    // '&Tags=' +
    '&ListNumberOfPage=' + counter +
    '&ListItemsPerPage=5' +
    '&GroupID='+GroupID +
    '&SortBy=PriceASC' +
    '&ResponseDetails=List',
    headers: {
      "User-Agent": "Tredix CaKe Client"
    }
  };

  var ifsRequest = http.request(options, function(ifsResponse) {

    var responseBody = "";
    ifsResponse.setEncoding("utf8");

    // echo some IFS response details
    console.log('STATUS: ' + ifsResponse.statusCode);
    console.log('HEADERS: ' + JSON.stringify(ifsResponse.headers));
    console.log('counter: ' + counter);
    console.log('################');

    ifsResponse.on("data", function(chunk) {
      responseBody += chunk;
    });

    ifsResponse.on("end", function() {
      // build static HTML for the client
      html="<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>";
      html+="<html><head><title>"+GroupID+"</title></head><body><table>";
      var hits = JSON.parse(responseBody),
      results = hits.SearchResult.ListHits,
      length = results.length;
      for (var i = 0; i <= (length-1); i++) {
        html+="<tr><td><b>"+results[i].Title + "</b></td><td><b>"+ results[i].Price+"</b></td></tr>";
        html+="<tr><td colspan='2'>"+results[i].Description + "</td></tr>";
      }
      html+="</table></body></html>";

      nodeResponse.writeHead(200, {
        'Content-Type': 'text/html; charset=UTF-8'
      });
      nodeResponse.end(html);

    });
  });

  ifsRequest.end();

}).listen(8124, "127.0.0.1");

console.log('Node server running at http://127.0.0.1:8124/');

No comments:

Post a Comment