Subtitel

A blog by Juri Urbainczyk | Juri on Google+ | Juri on Twitter | Juri on Xing

Showing posts with label Software. Show all posts
Showing posts with label Software. Show all posts

Wednesday, April 8, 2015

Implementing a REST API with node.js

Every so often there is the necessity to implement some mock-up web services or maybe even a prototype which shall offer its functionality via web services. This happened to me once again in March 2015 when preparing the API for a hackathon. To be precise, there already was an API, but it did not really fit to the requirements of the hackathon’s sponsor. Therefore, we decided to implement a second API (as a mock API) on top of the existing one. Our, second, API should add additional functionality to the existing services.
It was quite clear that the API should be REST with JSON as transport protocol. Unfortunately, we only had less than 4 weeks to design, implement and test the mock API. Thus, only a very lightweight technology could make this possible, like node.js.
Being JavaScript on the server, node.js is indeed a very lightweight technology. In its most basic configuration it will require you to write only one JavaScript file, which is then read and executed by node. Furthermore, it come with a module concept which lets you include already existing modules into your code with the “require” statement. Node also brings a packet manager (named “npm”) which lets you easily install all those modules to your project’s file system. In our mock API we used the following imports:
var http = require('http');
var express = require('express');
var url = require( "url" );
var path = require("path");
var fs = require("fs");
var queryString = require( "querystring" );

For our purposes, the “express” module is very important: it enables us to write REST services like in the following example. This short piece of code implements a web service, using the HTTP “GET” method, which echoes all input back to the response.

var api = express();

api.get('/echo', function(req,res) {

       var myobj = "";
      
        // parses the request url
        var theUrl = url.parse( req.url );
       
        //check if there is a query       
        if ((theUrl.query != null) && (theUrl.query != "")) {

             // gets the query part of the URL and parses it creating an object
             var queryObj = queryString.parse( theUrl.query );
              
             // queryObj contains the data of the query as an object
             // and jsonData is a property of it
             myobj = JSON.parse( queryObj.jsonData );                   
       }

       res.json( myobj );
});

As this examples shows, it’s really quite simple. For the response, you have to create a JavaScript object (which also might be a quite big one with arrays included and so on…) and transform it to JSON with “res.json”. This data is then returned to the client. There is a catch, though: with a HTTP “GET” method the input parameters will be encoded in the URL and therefore there is an upper limit of data which can be input to the service (around 8 kB, depending on the browser and other factors).  So, in order to potentially input more data into the web service, a “POST” method should be used, like in the next example. This one also shows how to extract parameters from the request header and do some basic authentication. Anyway, please bear in mind, it's still only a prototype source code (e.g. there should be another return code than 400 if an error occurred).

api.post('/api/booking', function (request, response) {

     //Read header & body
     var jsonData = request.body.requestPayload;

     var requestID = request.header('requestId');
     var userName = request.header('userName');
     var userPassword = request.header('password')
     var timeStamp = request.header('timeStamp');

     if (!checkAuthWithResponse(userName, userPassword, response)) return;

     resultAsString = '';

     var err = oVali.runHeaderValidation(request);
     if (err.length > 0) {
  
          // some logging and error handling here
     } else {

          // some business logic here

     }

     Response.send( resultAsString, 400);
})

Our mock API was intended to implement additional business logic on top of the existing API. The client would then call the mock API’s services to execute this business logic. Because the logic would only be depending on the values of the input parameters of the services there was no need for additional data storage or caching. Nevertheless, it would be quite easy as well to integrate a NoSQL database into node.js, for example.
Our mock API based on node.js was implemented just in time for the Hackathon and it was used there with very good results. We experienced no outages and had no problems with the performance as well.

As a summary, what are the advantages of using node.js for REST API development? We can name the following:

  1. As a developer, you are up and running very quickly. Install node, download some modules, write ONE file, and you are done.
  2. You don’t need to learn a lot of tools and IDEs (low overhead).
  3. The feedback cycles are very short, enabling you to develop with high speed.
  4. Integration with file system and databases is easy.
  5. Many standard problems can be used out-of-the-box with only a few lines of code.
  6. There is a big community, helping you out if you run into problems. Online documentation and FAQ is huge.
  7. It’s very easy to transport node projects. Just zip and unzip the files and you are done.
  8. There are a lot of possibilities to deploy and run node projects on the web. Pricing starts very low as well.

The bottom line is: node.js is a perfect choice for implementing prototype REST services. In how far this could be extended to full blown operational services – that’s another matter.

Thursday, March 19, 2015

Top Ten Tips for Hackathon Organizers

Want to organize a Hackathon? Great idea! A Hackathon is an amazing opportunity to collect new ideas, learn new stuff and get to know interesting people. Here, I'd like to share with you my personal experince from past Hackathons.

1. Have a goal
Communicate the objectives and goals you want the participants to achieve clearly and without room of interpretation. Tell them your criteria to judge if the the goal has been reached. That will enable the participants to think in the right direction and it will help you to easily find the winning team. Whether its to try out your API or to construct some fascinating algorithm - write it down and stick to it. BTW, also tell them about the prices as well :-)

2. Know the technology
You really have to be knowledgeable about your technology. And: you must be able to explain it to the participants. Tell them which technology to use, how to use it and what bugs and issues are known. They don't have to try it all out for themselves - that will only lead to frustration - and time is short. You really have to know your ropes concerning APIs, protocols, data models and frameworks. Be prepared to answer questions, so better think before, which might come up.

3. Built a protoype
There is nothing better to prepare for a Hackathon as to do everything you expect from the participants yourself in advance. Of course, you might not be as fast as they're gonna be, and you might not have a UI so pretty - but hack some code and try it all out, because only then will you really understand the relevant challenges with the technology. An then, if your prototype is ready, bring it and use it for reference.

4. Keep it simple
Time is running twice as fast as normal at a Hackathon. Or maybe even faster. So, nobody will find it amusing to read through handbooks to understand you challenge. So, keep it straight and simple. Remember, people are there to have fun and hack away freely. If possible only make them use ONE API not many, and only ONE protocol or data format. Use JSON and REST, instead of XML and SOAP. If possible leave out authentication. And avoid any extra overhead like having them deploy every hour or having them use a unknown tool.

5. Write documentation with sample code
You should write documentation for everything you want the participants to use, that will keep them from asking you everytime, The documentation should be proof-read to be as error-free as possible. It really has to be, so stay focused to keep if correct. And insert code snippets into the documentation which can be copy-pasted into their code and which should run out-of-the-box. Beware, some programs have problems with copying to the clipboard, like some acrobat versions, which distort the characters.

6. Bring all the stuff
You should not turn up there empty-handied, but rather carry a real large bag. You should bring a lot of marketing material, like banners, stand-up figures, mugs, T-shirts, stickers and everything a developer might love. Also bring all technology you might depend on, like projectors, adapters, notebooks and presentation software. If you need your laptop with the old VGA output, bringt the corresponding adapter.

7. Plan time before and after the event
Your technology and all relevant documentation should be up and running latest one week before the show. The participants just need some time to prepare themselves. And then, after the event let it all stay up and running for at least a week as well, because thedevelopers like to show off and tell their friends and collegues about it.

8. Dont show up there in a suit
And a tie is no good either. But bring a sleeping bag.

9. Collect the results
Be prepared to gather everything they produced at the event. You will need some time for that and better before the final presentation. So there should be dedicated people going around to collect all stuff. Perhaps you need a repository for that. And if you cannot get the code or the running system, then let them provide at least screenshots and/or movies - and their contact data.

10. Know your data
I experienced, that most teams show up at the Hackathon with a firm idea of what to build already in mind. And for this idea, they might need a certain dataset. So, if you cannot tell them how your data is structured and what the limits are, they won't have a good time. Be prepared to alter the dat if necessary or even to import extra data at the event.

Hackathon - Definition

Tuesday, November 19, 2013

Devoxx 2013 - The coming of lambda

It’s November 2013 and it’s conference time again. The European Java and Web Community gathered in Antwerp for the annual DEVOXX conference, which always means days tightly packed with information. My head is still spinning but I’d like to highlight a few things which are noteworthy this year. But first, a picture from the first keynote session, showing live-DJ-ing with software scripting:


No single hype

This year, there was no unique theme standing out. The hypes of the years past, Mobile, Cloud, NoSQL, BigData, are now regarded as standard. There were still presentations about those topics, but they are “normal” now. This of course is a good thing, although great emotions and extraordinary news are missing.


Java 8 expected with Lambdas and support for parallel execution

There were a lot of talks on Java 8 and on the new features available with Lambdas and functional / declarative programming.  They especially seem to enhance code readability which is important because “reading code is more important than writing code” (Brian Goetz). The most prominent example is the replacement of the infamous anonymous inner classes through lamdbas. This can be seen in the following code sample:

public class MyListener {
  public static void main(String[] args) {
    JButton myAnonymousButton = new JButton("A Button");
    
    //actionlistener using anonymous class
    myAnonymousButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        System.out.println("anon click!");
      }
    });
    
    //actionlistener using lambda expression   
    myAnonymousButton.addActionListener(e -> { System.out.println("a lambda click!");
    });

    JFrame frame = new JFrame("Functional Sample");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(myAnonymousButton, BorderLayout.CENTER);
    frame.pack();
    frame.setVisible(true);
  }
}

Internally, the lambdas are implemented using invokedynamic which was introduced in Java 7. By doing so, the JVM can choose that implementation of the lambda which it sees fit. This is an advantage, since at programming time you don’t necessarily know the concrete circumstances of the runtime environment. On the other hand, the programmer loses control, because he only tells the JVM what to do but not how.
There is also a new stream library coming, which especially intends to simplify parallel programming. I’m not sure how much of a performance gain this can achieve, because it half of the code can be parallelized, the program can only run twice as fast.


Microsoft is Sponsor now           

The Devoxx organizers can be happy, because the “big four” are sponsors now: Google, Oracle, RedHat and Microsoft. Google dominated the talks, while, strangely enough, Microsoft did not show up in any of the presentations (although they had a booth). This is really a chance missed, especially since Windows 8 opened up to the Web and allowed for Windows Applications being written in JavaScript and HTML5.


More crowded, but…

Devoxx 2013 was even more crowded than the conferences of the last years. It was harder to get a seat for the important presentations and it was a pain to get something to eat. This all is ok, if the costs are low (which is true) and if the quality of the presentation content is high (which is not so true anymore). Actually, the quality of the slides was a catastrophy! I cannot remember another conference in the last years where “death by bullet point” was so imminent. Many presenters even read all their slides aloud and some did seem to be on the edge of sleeping (or at least trying to get their listeners to sleep). What’s more, good talks on methodology and architecture were missing, while many presenters focused on detailed features of various (sometimes not so important) frameworks. I also missed great keynote speakers. To wrap it up: quality at Devoxx seems to be on the decline. Maybe it’s because there are a lot of Devoxxes out there now (London, Paris, Kids …). Do they lose focus?


Highlights

Nevertheless, there were some very interesting and entertaining presentations: The session on Google Glass was absolutely packed and really lived up to the expectations. Another good one was Arun Gupta talking about web sockets. Also, Brian Goetz on details of the JVM and Ludovic Champenois on Google App Engine excelled. Next time, get us more of those, please.

Saturday, October 19, 2013

Portal Anti-Patterns - Installment 1: Misuse of portlets

In my IT consulting projects I regularly get the chance to inspect enterprise web portals and to take a deep look at their software architecture. What my team and I find there is troublesome at best. And the problems are the same in nearly all the portals I checked, thus it’s sensible to call them anti-patterns. They present a great opportunity to learn from mistakes already made lest you don’t repeat them.
In this little series I’d like to share this experience with you. This time, my topic is the use (or rather misuse) of portlets.

Anti-Pattern: “Page Portlet”


Portlets are a great way of bringing modules to the user interface. They also offer possibilities of reuse while at the same time encapsulating logic and data. Therefore, as a best practice, a portal page is expected to consist of multiple portlets, a reasonable number being 3 to 8. Nevertheless, I often encounter the so-called “page portlet” syndrome: each page of the portal is made up of one single portlets (or sometimes two portlets, one of which only represents navigation of header or something similar.
"Page Portlet" Anti-Pattern
This spoils all the positive aspects of portlets. Above all, portlets of this size are often so specific to a certain use case, that reuse is not possible effectively. Furthermore, it prevents approaches like responsive design to work on portlet level – everything has to be implemented in the portlet and thus cannot be configured and controlled by the portal server.

A “page portlet” should only be used as an intermediary step, when an application has to be split up into multiple portlets but in the current release there was not enough time to accomplish that. Then, you could tentatively integrate the whole application as one portlet into one portal page – but certainly not as final solution.

Monday, July 15, 2013

Software Architecture - more than documents

As I read the following sentence in an IT magazine some days ago it immediately caught my attention: „Also, in smaller projects architecture (the documentation of the software solution) is obligatory. “.

That is, where I have to object: architecture is not only the documentation. Architecture even exists without any documentation, and it can be a good one, mind you. These days, many people tend to overly concentrate on the documentation of the architecture rather than on the methods and processes needed to conceive it. For instance, the arc42 template is a good one (and I don’t want to be misunderstood on that) but it also only focuses on documentation.

According to my understanding (and I am talking mainly about software architecture here – as opposed to business architecture, for instance), architecture refers to three different aspects:
-         the process of conception of the software system (some people call that “technical design”)
-         the inner structure of a software system (and its sources)
-         the documents needed to describe that structure (e.g. component view)

These three aspects are correlated. The following diagram depicts this relationship.
Picture 1: The three aspects of software architecture
Although correct and sound documentation is necessary to understand and communicate the architecture, it is not the same as the architecture. If we would conceive, design and build an app with an excellent architecture and install it and after that throw away all the documentation, the architecture would still be in existence, would still be splendid and would hopefully still exhibit all the nice quality criteria it was designed to. Our app would still be very stable and would respond to user input very quickly.

As I wrote in another post, software architecture is a set of concepts which resolve the functional and non-functional requirements of the system (cf. http://juriswritings.blogspot.de/2012/03/what-is-software-architecture.html). Therefore, these decisions must be safe and sound. In order to make sensible decisions the architects above all need experience and good requirements documentation (e.g. domain models and use cases).

As the project progresses and the bigger the project gets, the architects also need models of the architecture, because they may have to make decisions which change parts of the architecture already discussed. Thus, documentation is important, not only to help new people to get on the project and to let people do maintenance later. But – and that is my point here – it is not the same as the architecture and it is also not the first thing which needs to be created. Architects have to decide and they have to invent sensible concepts. Documentation is merely a tool to help them do their work – and we should keep that in mind when documenting.

BTW: the said article is “Architecture for eternity” in “Entwickler Magazin 04/2013” by Nils Arndt. The sentence is below the fourth sub heading, which is on page 2 of the article.

Tuesday, June 25, 2013

An HTML5 canvas component for ExtJS 4

As I described in another post, ExtJS 4 features components for graphics ("Ext.draw.Component") which are based on the standard HTML SVG tag. But what if we liked to use a <canvas> tag? ExtJS does not bring one of those - thus we have to create one.

We also need a nice little showcase. For that, I implemented a small application, which simulates a solar system, with a configurable number of planets, moons and stars. The application calculates the gravity which affects the objects and then determines their new positions. This is done repeatedly, leading to a simulated continuous motion. The positions (and trajectories) of all objects are displayed in the canvas element. Picture 1 shows the solar system simulator in action.
Picture 1: Solar system simulator written with the canvas component
I put the canvas component in a separate file (canvasPanelClass.js), thus it should be easily reusable. The component utilizes the powerful object-oriented features of ExtJS. It extends Ext.Panel and creates the canvas element in the constructor method. In the afterrender listener (when the component already is complete) it stores a reference to the canvas in a private variable (this.canvas = this.items.items[0].el.dom;).

After that, the canvas is ready to be used. The component already brings some important methods, e.g. drawCircle( 50, 50, 10, "red" ) which draws a red circle with a radius of 10 pixels around the point 50, 50.

And now, the most interesting part of the source code:

        Ext.define('CanvasPanelClass', {
            extend: 'Ext.Panel',
           
            gridColor: '',
            ctx: null,        // is set when rendered
            canvas: null,    // is set when rendered                       
            bodyStyle: { background: '#000' },
            frame: false,
            margin: '2 2 2 2',
           
            listeners: {
                afterrender: {
                    fn: function(){                       
                        this.canvas = this.items.items[0].el.dom;           
                        this.ctx = this.canvas.getContext("2d");                                       this.clear();                       
                    }
                }       
            },           
           
            constructor: function(config) {
               
                //define this here because we can set width and height
                this.items = {
                    xtype: 'box',
                    autoEl:{
                        tag: 'canvas',
                        height: config.height,
                        width: config.width
                    }
                };
               
                this.tempCanvas = document.createElement("canvas");
               
                CanvasPanelClass.superclass.constructor.call(this, config);
            },
                    
            drawRect: function( x, y, width, height, lineWidth, color ) {
                this.ctx.strokeStyle = color;
                this.ctx.lineWidth = lineWidth;
                this.ctx.strokeRect(x,y,width,height);               
            },
           
            fillRect: function( x, y, width, height, color ) {
                this.ctx.fillStyle = color;
                this.ctx.fillRect(x,y,width,height);               
            },       
           
            drawCircle : function( x, y, radius, color ) {
                this.ctx.beginPath();
                this.ctx.strokeStyle = color;
                this.ctx.fillStyle = color;
                this.ctx.arc( x, y, radius, 0, Math.PI*2, true );
                this.ctx.closePath();
                this.ctx.fill();       
            },           
           
            putPixel: function( x, y, size, color ) {
                this.ctx.fillStyle = color;
                this.ctx.fillRect(x,y,size,size);           
            },

                  
            clear: function() {
           
                // Store the current transformation matrix
                this.ctx.save();

                // Use the identity matrix while clearing the canvas
                this.ctx.setTransform(1, 0, 0, 1, 0, 0);
                this.ctx.clearRect ( 0, 0, this.getWidth(), this.getHeight() );

                // Restore the transform
                this.ctx.restore();                                      
            }


        }); // define CanvasPanelClass

Then, the canvas component can be used like in the following code snippet. (There is an array of canvasPanels because you might want to create more than one canvas.) The mousedown handler shows how an application can react on mouse clicks into the canvas.

      canvasPanel[0] = new CanvasPanelClass({
            height: 500,
            width: 500
      });              

      canvasPanel[0].on({
            mousedown: function(DOMevent) {

                             var canvasPanelX = this.getPosition()[0];
                             var canvasPanelY = this.getPosition()[1]
                             var point = DOMevent.getPoint();

                             var eventX = point.x-canvasPanelX;
                             var eventY = point.y-canvasPanelY;

                              // do something …

                             canvasPanel[0].clear();
                             canvasPanel[0].renderGrid(25*50/ZOOM,GRIDCOLOR);
            },
            element: 'body',
            scope: canvasPanel[i] //Ensure "this" is correct during handler execution
      });

      tablePanel.add(canvasPanel[0]); 
  
      canvasPanel[0].clear();    

      canvasPanel[0].putPixel( 50, 50, 1, "green" );