 | Level: Introductory Peter Seebach (seebs@plethora.net), Freelance author, Plethora.net
27 Feb 2007 Writing local Web applications can be quick, easy, and efficient for solving specific Intranet problems. Understand why a Web browser is sometimes a better interface than a GUI application, and when a CGI script may be the simplest and most elegant solution.
The vast majority of Web sites you visit are presumably open to Internet
access, but many companies have found that Intranet development has its place.
However, you can take this further -- you can develop perfectly functional Web
applications that will never send so much as a single packet over a network
interface. Experienced Web developers sometimes find themselves struggling
to learn a GUI toolkit when a simple CGI script would serve their needs
perfectly well.
A local-only Web application is, if anything, much simpler than one intended
for general use. You can easily set browser requirements, and server
performance is very unlikely to be an issue. Simple applications, using
standard CGI form widgets and the like, can be written in a fraction of the
time required for development of self-contained applications. Applications
that are built around forms or data manipulation are often excellent
candidates for implementation as a trivial Web service.
In many cases, a custom application like this can provide an elegant and
simple solution to a very specific problem. I once wrote a picture
browser that did nothing but browse a single directory full of files
from a camera and let me file the pictures into categories. This took
maybe twenty lines of Perl, and the result was much faster than a more
general solution, to say nothing of how long it would have taken to
write a GUI application to do the same thing.
What has the Web browser done for us, anyway?
You might ask, quite reasonably, Why would anyone bother? What does the
Web browser do that another application can't do? The answer is obvious:
nothing. But then, what do high-level languages do that you can't do in
machine code? Nothing, really. The advantage of using a Web browser as your
interface is that all the hard code has been written already. You don't
have to run around checking for resize events, window expose events, or
menu events. All you do is read a chunk of data expressing a request and
process it.
The potential weakness of Web-based development is lack of control over
appearance. This is not much of a weakness. If you're trying to get an
application developed quickly, the last thing you want is to spend a lot of
time messing about with appearance. Whatever platform you're on, the Web
browser's native buttons and text widgets will be familiar to the user.
That's a feature, really.
The Web browser does one more thing that is very useful: It gives you a number
of preference settings you're not required to maintain yourself. Font sizes can
be changed by the user on the fly. Similarly, if you can generate your output
in a nice, simple HTML form, it can be printed easily and quickly. Many
features you might otherwise have to implement (saving output to a file,
printing output, and resizing windows are just some examples) are implemented
for you.
Architecture for the single user
Although it might seem that a single-user environment completely eliminates
a lot of application development considerations, this isn't quite the case.
I recently wrote a document-filing system as a Web application. Because I designed
it for a maximum of one simultaneous user, I felt I could dispense with a lot of
the file-locking code that might otherwise be necessary. I was wrong. The
user interface utilized frames, and one of the sanity-checks performed by my
display program could fail catastrophically if another program
modified the database while it was running. The browser would often end up
running both queries at once.
A local server means that network bandwidth is not an issue; even things that
might be problematic on ethernet are not a problem on a local host, although
huge files will still slow down or crash browsers.
Network security
If you are developing an application to run on a local Web server, give
thought to the question of what happens when someone else accesses it over
the network. Ideally, ensure that the local application is only accessible
on the local network interface. If you can't do that, you will need some
kind of security. It might be enough to simply have your application refuse
all connections that aren't from 127.0.0.1, which is a lot more secure than
password-based security.
It might be reasonable to simply pick an alternative port number so you can
have a dedicated server for your application. On a UNIX®-type box, setting
up a personal copy of Apache on port 8880 will take minutes and gives
you complete control over server features and settings. It also ensures
that your application back end runs with your usual privileges, so you don't
have to make crucial files world-writeable, which is a big plus.
Data management
For a traditional Web application, using a database server on the
back end simplifies development immensely, because the database engine --
just by being a single server -- provides most of the serialization and
locking you need, and more can be obtained easily. For a single-user
application that's going to run on a single machine, this is probably
overkill and might not be worth the trouble. A local application might have
no need of this and might benefit from using a simple and easily moved
data file. I would move my document-filing application between my laptop and desktop computers whenever I went anywhere. This
was trivial because it simply used a Berkeley DB file.
The Berkeley DB format offers a fairly simple solution that is easily
accessible from a number of languages. Because there's no database
server involved, it's a poor choice for an application with many
simultaneous users; to be safe, you have to lock the database, perform
your operations, and then unlock it. On the other hand, because no
database server is involved, it's a fairly good choice for a program with
very few simultaneous users.
Here's sample Perl code to attach to a Berkeley DB database, complete
with locking:
Listing 1: Attaching a database
my %db;
open(DBFILE, '+file.db');
flock(DBFILE, LOCK_EX);
$dbhandle = tie %db, 'DB_File', 'file.db', O_CREAT|O_RDWR, 0666, $DB_HASH;
|
After this code has run, you can access the database directly as a standard
Perl hash:
Listing 2: Using a database
$db{user} = "me";
print "<p>User: $db{user}</p>\n";
|
You can also use the dbhandle object to perform operations on the database:
Listing 3: Using a database handle
When you're done, you're done -- that is, when your program exits, the
lock is dropped automatically. The flock()
locking is purely advisory -- it won't prevent other programs from
writing to the file if they don't use it. If your program is implemented
as a number of related programs, put the locking code in all of them, or
better yet, put it in a shared module. This way, the purely advisory
locking still gives you what you need: reliable assurance that only one
program at a time is modifying the data files.
Some applications will work fine with plain files, such as CSV files
or just flat field text files. Some might need a full SQL database. Don't
feel compelled to adopt "enterprise-class" solutions for small
applications that are intended to get a job done quickly and easily.
Save your effort for good error recovery and nice convenience features.
That said, if you need a relational database, use one.
Interface widgets
Applications are probably reasonably well addressed using forms with
lots of buttons in them. If you have metadata or context that needs to
be passed from one page to another, go ahead and use hidden form fields;
the security concerns you might face (users can override them) are
non-issues in this context. You can use image buttons for many purposes,
although they do require you to develop images. If you want to bypass
this, create an image button with alt text and an invalid URL for its
image:
Listing 4: A text-only button without GUI widgets:
print $q->image_button(-name => "sort",
-value => "$name",
-src => "/nonexistant",
-alt => $label);
|
This might seem ridiculous, compared to the simpler alternative of just
using a hyperlink, but in a large form, the corresponding href=... link might be quite large, and indeed
impossible to precalculate if the button is submitting a form. It's an
ugly hack, but it works.
One-off applications
If you write a couple of small local host Web applications, you will quickly notice
something: They are often quick enough to write, even with debugging, to be
substantially more efficient than performing common tasks by hand. The
efficiency gain of simplifying a long or tedious procedure might easily pay
back the development time of an application that might take only minutes to
develop.
Perl's standard CGI library provides a huge variety of useful basic tools
to work with. A couple of hours of playing around with it and getting used
to its extremely flexible and rich feature set will let you write a broad
variety of applications with very little effort. Just as a simple scripting
system can make one-off command line scripts practical and cost effective,
simple CGI scripts can make a variety of graphical programs practical and
cost effective. If you put an afternoon into playing around with these,
you'll quickly find that dozens of tasks that you wish someone would have
written a program for are easily within your grasp.
Scaling up
A disturbingly common experience is to write a small, simple, one-off
application, quite possibly intended only for local use, and then discover
that there's a compelling reason to scale it up to a larger audience.
Even when an application is only for local use, write clean code, and have
lots of instrumentation and debugging output available. Good code with
good support for debugging pays for itself in maintenance costs very
quickly. When you add in the possibility of needing to rework the application
for a larger (plural!) audience, it pays off even more.
Refactoring can be a fair amount of work, but it's not as bad as you might
think. For the most part, it will mean scaling up the actual back-end
database or file manipulation to allow for better and smarter locking. If
your program does file manipulations, you might consider writing a small
server that handles these operations atomically, and thus guarantees
serialization. It might well make sense for such a server to handle only one
client at a time, as long as individual scripts run quickly.
The major thing you need to watch out for is a program that assumes something
about internal state. For instance, in a document-classification program,
the obvious thing to do is to display "the next file" to the user, then file
it appropriately. With two users, you need some tracking of which file each
user is processing, and some way to handle edge cases -- if someone opens the
application, then wanders away at some point, you will need to let someone
else look at the file in question. Sometimes this can involve a substantial
rework of the back end, but it will generally be pretty easy to keep the
user-visible front end stable.
Resources Learn
Get products and technologies
-
Build your next development project with
IBM trial software, available for download directly from developerWorks.
Discuss
About the author  | 
|  | Peter Seebach thinks that CGI is probably one of the best GUI toolkits he's ever used. |
Rate this page
|  |