Home Updates Messages SandBox

GUI contra WWW

It seems that many programmers have a problem when trying to switch from making their everyday graphical user interface applications to writing web applications. This is no surprise, as they both require quite radically different approach and philosophy. I will try to explain how the web applications usually work, in hope of making it easier for these programmers.

Long, long time ago, when computers were the size of a building and you had to write "programmes" by punching holes in special cards, the communication model was pretty simple: you punched some cards, in specified order, and sent them for calculation. Few days later you received the paper printouts with the results in your inbox. Then you either corrected your program (if the printouts happened to be error messages) and sent them again, or used the results you obtained. Obviously, you could only do any input by hard-coding it in the program itself, and there was no way to store any intermediate data in the machine – it was reset before each computation. It was laborious, time-consuming and expensive, but that's how it worked.

Later, it was slightly improved. You had a teletype machine connected to the computer. You could issue commands by typing them on the keyboard, and the results were printed on a sheet of paper in front of your eyes. They were calling it "interactive computers". That's where the command line was born: you type your command, followed by any options, attributes and parameters that are needed, and in several minutes you get back the result of that command, printed on paper. At that time computers could actually handle more data than you could comfortably type in, so you were also able to use additional data stored on tape drives and other storage – you did it by specifying the source of that data in some of the commands. The program would read the parameters that were passed in the command, then read the data from the storage, then either spit the results on the printer or back to the storage. After that, it would finish and you would be free to run a different program. There were interactive editors and similar programs, but they were not really very easy to use, mostly because of the limited speed of the communication.

The web applications have a lot in common with this kind of programs – with just small differences. Instead of the command and its parameters, you have the @URL@ of the web page. Instead of printing the result, you display it in the browser. Of course, there are also differences – the whole thing seems to be a lot more interactive, because instead of laboriously typing the command on a teletype keyboard, the users interacts with a graphical application, the web browser, and either selects ready-made commands by clicking on links, or fills in parts of predefined commands, by filling forms. But you have to remember, the user interacts with the web browser, not with your program. The interaction with your program only happens when a new URL is sent to the server as a command, and a new page is displayed in the browser as a response. Each time such a command is issued, your program has to prepare the response without knowing anything about previous commands – all it knows is the @URL@ and the data that is stored on the server. It doesn't even know if the previous command was issued by the same user.

Obviously, this model of interaction can be modified by using browser scripting and various browser plugins, as well as cookies and user sessions – but these are exceptions rather than the norm and you should only use them when you actually need them. There are lots of reasons for avoiding them, and we will get back to them later. Web applications that don't use these hacks are often called "stateless" or "RESTfull", and they work very well with the existing architecture of World Wide Web.

RESTfull approach to application design requires you to think of it as a set of elements, objects with their own representations as web pages, connected with links and forms – rather than a process, a sequence of actions, a procedure. You must remember, that the URLs can be visited in any order, without any relation to each other – for example, the user can bookmark a page, or send its address to his friend in an e-mail – and it shouldn't break your application, it should still behave as expected. This is usually achieved by first identifying the components that the user is going to manipulate, and then provide pages representing them. You can use most of the methods of identifying objects known from the Object Oriented Programming techniques – except that the objects will only send very few signals between each other. You usually end up with a bunch of "index" pages, containing various lists of links, and "leaf" pages, containing descriptions of single objects. Sometimes such a leaf page will also contain a list of links related to related objects.

Consider an example: a simple web application for managing students. The objects would include students, teachers, student groups, lessons, courses, exercises, homeworks, grades and a bunch of similar things. Some of them are obviously containers: student groups contain students, homeworks contain exercises, students have grades, etc. Others are more independent and have a lot of data associated with them. It's therefore natural to have a separate URL for each of these objects, and a representation of that object displayed under that URL. You also need some additional means of navigation between them, and possibly a search functionality, but that's secondary. You might want to have the editable versions of these pages at separate URLs, but that's not a requirement. That's how a web programmer would think about such an application.

A GUI programmer might choose a different approach, and it'd give him a lot of headaches. You see, he's got all those user stories, use cases and "functionalities" he's got to implement – so he just does it. He thinks "there must be a way to create a group and assign students to it", so he makes a "create group" button, which takes the user to a "wizard" – then the user is presented with a series of pages representing steps of group creation. "There must be a way to review the homework" – so he makes a "review homework" button, which takes the user on a ride through the "homework review wizard". And so on. What's wrong with this approach? It's stateful, the server has to remember what is going on for every user and which step to present next. The user also has to remember it, and he can't just interrupt the work and come back to it later, or send someone a link to what he is seeing on his screen – sometimes even the back button and the refresh button won't work properly.

Of course, in the world of GUI applications both approaches are possible – and the latter seems to be somewhat trendy recently, especially among the low skill windows programmers who themselves use "wizards" to do their programming. In the world of WWW, however, the second kind of design is extremely costly to implement and maintain, and confusing for the users who are used to RESTful web pages. It's also inefficient – forcing multiple reloads and requiring transfer and storage of additional state information. It's insecure, making the application vulnerable to all sorts of cross site scripting and replay attacks. Finally, it's uncomfortable, limiting the users to what the programmer thought of and disabling a lot of functionalities that web pages normally get for free. In short, it's bad for you, don't do it, learn to design with REST in mind. You will make the life of yours and your colleagues much simpler.

Thank you.