Programming - - By Harry Fuecks

Crouching Javascript, Hidden PHP [2]

Continuing yesterday’s rant, this installment should (hopefully) get a bit more juicy, if I can work out where it’s going.

First up, already some good feedback to the last part (thanks!), most to-the-point being Alan;

I can tell you having worked with SOAP, various RPC layers, and simple GET/POST / XML parses, that most of the time RPC tends to suck big time, It’s great for the first 3 test calls, but as a project grows, there is a point where it doesnt work as expected. You then enter one of the worst nightmares in hell to debug.

When javascript (especially if you are risking life and limb trying to get a MS implementation to work) comes in, it’s alot easier to stick with the basics.. KISS / POST/GET/ strings and XML as needed..

Also interesting is Danne Lundqvist’s similar but alternative approach to what Javascript Serializer does with script src attributes; manipulating the attribute using the DOM which he describes here.

What’s up with Javascript

Returning to the thought from last time: “It’s 2004. Someone must have solved this once-and-for-all by now.” (the problem being how to we pull fresh data from the server into a page that’s already loaded), think it’s worth trying to understand (guess) why “things” haven’t progressed further.

Think the starting point there is asking “what’s up with Javascript?” which really is a puzzle.

If you really take a close look at the ECMAScript spec (long story short: ECMAScript == Javascript) and do some serious delving with a decent implementation like Mozilla’s you might come to a stunning conclusion – as a dynamic language, the design is excellent.

Although Javascript is generally applied only to the very specific purpose of browser scripting (so there’s a ton of problems it’s design has never really had to incorporate), you could reasonably ask why Perl or PHP aren’t built so cleanly. Try this in PHP, for example;


try {
eval( someJsInThisVar );
} catch ( e ) {
alert ( "Syntax error "+e+" in "+someJsInThisVar);
}

…or, as I was talking about here, attaching new functionality to fundamental objects like;


String.prototype.toPHP=function() {
var s = this;
return 's:'+s.length+':"'+s+'";';
};

So if we say Javascript is actually a pretty good programming language, why isn’t put to more extensive use. Today it still seems relegated to adding the occasional simple gimmick to a web page, while being dubbed as the worst invention ever by members of the W3 committee (nice response to that here BTW).

Douglas Crockford pretty much sums it up in The World’s Most Misunderstood Programming Language. I’d also add XML parsing to the causes Douglas mentions – DOM often isn’t the easiest way to do things – Javascript needs a native SAX parser (although you can find a pure Javascript implementation here), a pull parser and something like Simple XML IMO.

Ultimately Javascript uptake boils down to developer good sense – it was, in the past, too easy to waste countless hours writing and debugging Javascript, across multiple browsers. Hours which could have been avoided by shifting a more to the server side, where you have an environment you could trust. Only a few have been bold (or insane) enough to do heavy loading with Javascript.

I say in the past because I think Mozilla has changed that – we’ve now got an implementation we can trust plus tools like Venkman to help out (side note – these days I find unit testing eliminates much of the need for debugging – jsunit seems to be about the best choice for Javascript).

Today, if you write for Mozilla first, Microsoft’s recent JScript implementations turn out to be close enough to only need minor tweaking to get stuff right. There’s the occasional aaaarrggh! like this;


Foo.prototype = {
x: 1,
y: 2,
}

IE (last time I looked) doesn’t like that second comma (had to get if off my chest).

Hooking up the Server and Client Side

My fundamental view of the client side has always been “I rather do this server side”. Part of my motivation there comes down the points Douglas Crockford makes; a historical mistrust of Javascript. But that’s begun to change to Mozilla.

But there’s another, more critical point which constains doing really funky stuff with Javascript, something I haven’t seen discussed in detail.

If I’m building a dynamic application which is primarily server-side, that’s already enough complexity to deal with – adding another layer of logic in Javascript, on the client side, is asking for nightmares (as Alan points out).

The big issue IMO is breakability – if I make changes to the server side, it’s too easy to break the client side inadvertently. That’s because I’ll typically be evolving the two more or less independently.

Although there’s obviously a relationship between them, there’s no built-in connection so changes to the server side aren’t guaranteed to be reflected on the client side.

Breakability

Returning to earlier points, in assessing the various techniques to pull further information from the server side, without reloading the entire page, think a key point in assessing their relative merit is breakability (to abuse the English language some more). If you make changes over here, what are the chances you broke something over there?

Taking the GMails frames + intensive Javascript approach to task (overnight I now have an account – many thanks for the offers!), I see it as highly breakable. It may not be a problem for Google, who have the staff to get it right but much of the relationship between server side elements, from the point of view of the user, is deeply embedded in the client side. A naive question perhaps but what’s the impact of, say, changing the name of a GET variable server-side?

Similar thoughts cross my mind when thinking about Livesearch. How easy would it be to build and manage a complex application based on the same approach? That’s not to say it can’t be done but I assume Christian maintains the client seperately from the server. And the server uses CSS classes which are defined here. On the one hand Livesearch is the epitomy of KISS. On the other hand, do the dependencies between various independent entities (Javascript, CSS and PHP) really amount to inherent complexity?

So I guess the question boils down to how do get changes to the server side to propogate cleanly to the client side?

A Lesson from SOAP

Think SOAP has got one (but not more) redeeming feature. And in fact it’s not defined by SOAP itself but rather WSDL. WSDL means accessing a service like Dietrich Ayala’s WhoIsGoingToBePresident service with PEAR::SOAP can be reduced to just;


getProxy();

$Prediction = $Predictor->whoisgoingtobepresident();

echo 'Kerry: '.$Prediction->kerry.'
';
echo 'Bush: '.$Prediction->bush.'
';

WSDL provides a precise definition of the service to the point where clients for the service can be generated and used simply by knowing the URL to the WSDL document. You don’t need to care about the underlying network or the data encoding required to allow it to be passed over the net.

In terms of yesterdays rant, the mechanism and payload have been taken care of without you needing to think about them. All that’s left is population – displaying the data in a visually appealing manner. If there remote service changes, of course it’s going to break your UI, but you’ll only need to think about making the right RPC call and tweaking the way you display the result.

In my opinion, hooking up the server side and client side of a web application needs to be this easy. At the same time, there’s only the Mozilla SOAP implementation out there and last time I tried it wasn’t a pleasant experience. Also SOAP fundamentally means bloat, IMO – it’s just too much complexity for this problem. We’re not concerned with giving the world access to a web service – only interested in getting Javascript talking to the server side for a single application.

Javascript Generation

The other way to go, as I see it, is to cut out the middle man (WSDL) and have the server side generate Javascript primed to talk back to the server, leaving only the population to think about (where we probably want some level human invention for the sake of a good looking design).

In general, generating Javascript which reflects something happening server side can be made to work well.

PEAR::HTML_QuickForm does a nice job when it comes to validation, for example. If you specify a server side form validation rule, such as a regex to require alpha-numeric characters, QuickForm can also embed the same rule as Javascript in the output HTML, saving the user a page reload before finding out they made a mistake. There’s no need for you, the developer, to think about the Javascript – it’s generated automatically. Change the regex in PHP and the Javascript changes as well to reflect it.

We’ve used a similar technique in (obligatory plug) WACT with the tag, which performs client side autocompletion (try typing in the name of a country). There’s no need to mess around with Javascript by hand. In your HTML template you might have;


Then in PHP you can load the tag with a list of items to autocomplete against like;


$Page = & new Template('/form.html');
$CountryInput = & $Page->getChild('countries');
$CountryInput->setAutoCompleteList($listOfCountries);
$Page->display();

At not point are you confronted with Javascript.

So how do we apply code generation, in a useful way, to pulling data from the server side into a page which is already loaded?

Bearing in mind SOAP/WSDL, my view is the way to go is generating a Javascript client which takes care of the mechanism and payload and needs only to be called by a developer.

To avoid a long discussion, here’s how I think it should work, more or less, from the point of view of a developer working with it.

If I have a PHP class like;


class UserAdmin {
function & listUsers() {
return new DBC::NewRecordSet("SELECT * FROM users");
}

function deleteUser($username) {
$sql = "DELETE FROM users WHERE username='".DBC::escape($username)."'";
return DBC::execute($sql);
}
}

You should be able to register it with the Javascript script generator, perhaps something like;


$Generator = & new Javascript_Generator();

if ( isset($_GET['class']) && $_GET['UserAdmin'] ) {
echo $Generator->generate('UserAdmin');
}

Whatever this generates I can then call directly in Javascript e.g.;



It’s not quite as simple as that – there’s a need to define callbacks if we want to use async calls to the remote server and I haven’t discussed the PHP “listener” which responds to the requests like “listUsers”.

But that’s the basic idea. The generated Javascript client is built, using reflection, from the class I defined in PHP. In other words I can work with an object in Javascript which behaves according to a PHP class definition. The mechanism and payload are “invisible” to the code I write in PHP and Javascript – it’s just a question of populating the UI with data. The potential “breakability” is, hopefully, much lower and changes can be quickly propogated to Javascript.

Anyway – that’s where I’m hopefully headed with this thing – time is not permitting right now. Could it needs to be shot before it becomes a lengthy waste of time. I’d certainly love to hear better ideas (or best yet; that you’ve already done it).

More Remote Javascript
Finishing up, to give Jason yet more stuff to look at;

XML for Script Server-Side Proxies; more tricks with the script src attribute and a very clean implementation (part of a very cool Javascript library).

JSRS; uses Javascript generated iframes. If I understand it right, very cool as the iframes never get added to the document, just used to fetch remote data.

Remote Scripting with Javascript, IFrames and PHP (article)

Blueshoes JSRS – seems to be a fork from JSRS linked above which uses WDDX.

Anything else?

Sponsors
Login or Create Account to Comment
Login Create Account