Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Encapsulating web client side code in Perl modules?

by varian (Chaplain)
on May 07, 2007 at 11:05 UTC ( [id://613916]=perlmeditation: print w/replies, xml ) Need Help??

The notion that web applications have to respond to more than one context has always struck me as being less-than-optimal. Imagine a typical web form: we tend to use a Perl/CGI program to draw up the form (context 1) and when the user submits the form data some parameter gets checked to see what context we are in, and we accept the form data via the same program (context 2). The first lines of code in the program center around finding out what context it is supposed to be in. Furthermore the program has to have multiple sections of code, each dealing with actions related to a particular context.

More recently I played around with CGI::Ajax. Interestingly the Ajax web client/server communication concept deals with the context issue in a very clean and intuitive way. Instead of the usual submit-form action the web client will directly address my server side Perl sub e.g. to request a database and the page is updated using the return values from my server side sub.
To achieve this CGI::Ajax requires a few extra functions to reside in the web client to support communication with the server. Therefore it injects Javascript functions in the head part of the HTML form before that form is sent to the web client.

The concept of cooperation between client-side Javascript and server-side Perl where the Javascript is totally encapsulated/hidden within a Perl module strikes me as a promising approach: we can make the web client more productive without having to write an extensive amount of Javascript as some set of functionality can be provided via Perl modules.
I am looking for a few modules so that I only need to maintain Perl code while I can still benefit from web client side actions.

What is your (production) experience with these concepts? Any caveats? Any Perlmonks that have created Perl modules that encapsulate web client code e.g. to deal with drag-n-drop functions and server side actions related to them? Any stable interfaces that help cooperate with existing Javascript libraries perhaps?

  • Comment on Encapsulating web client side code in Perl modules?

Replies are listed 'Best First'.
Re: Encapsulating web client side code in Perl modules?
by gloryhack (Deacon) on May 07, 2007 at 14:30 UTC
    Caveats? Sure, here's one: Bye-bye browser back button and with it the principle of least astonishment. It can be worked around in a dirty hackish kind of way, but it's something to be aware of and always worked around if you care about it. The easiest workaround manipulates the browser history on each update, bringing the back button back into more or less normal operation, but then the astonishment (somewhat) remains because the browser history grows and grows and pushes things the user might want to get back to right off the stack.

    Howzabout a pitfall: It's asynchronous, so if the sequence of client side events matters you might be surprised every now and then. Suppose you're using (for example) a scriptaculous Sortable to permit the user to rearrange things, and you don't want to force him to poke a button to tell the server that he's done sorting so you're firing off an XMLHTTP request on every drop (via Sortable.update and Sortable.serialize). Wow, slick. BUT, it's asynchronous, so the sequence in which the user does things is not necessarily the sequence in which the server responses to those things are received by the client. You can't count on things arriving at your server-side application in the order the user did them unless you jump through some hoops on the client side to (FIFO) queue your XMLHTTP requests. Then, if the server goes away, you probably need something on the client side to restore the client to the last known good state. Hello, Astonishment :(

    You might give a look at HTML::Prototype and/or HTML::Prototype::Effects (scriptaculous "embedded" in Perl).

      Thanks Gloryhack for the pointers and for listing these caveats. Indeed one needs to be careful where and when to apply XMLHTTP requests.
      I am not too concerned about loosing backbutton functionality. This side-effect will be limited when one still uses regular page linking for a switch between menu choices and between forms. In fact the XMLHTTP requests can be used beneficial to prevent accidental re-posting of form data when the user hits a backbutton.

      The prototype links indeed appear to come close to what I was looking for and I will investigate them further. In particular I am curious to see how they would interact with Perl code back and forth.

      I am also grateful for the feedback from the other monks. As usual there's more than one way to accomplish things and the choices and tradeoffs mentioned provide insight.

Re: Encapsulating web client side code in Perl modules?
by derby (Abbot) on May 07, 2007 at 12:26 UTC

    we tend to use a Perl/CGI program to draw up the form (context 1) and when the user submits the form data some parameter gets checked to see what context we are in, and we accept the form data via the same program (context 2). The first lines of code in the program center around finding out what context it is supposed to be in. Furthermore the program has to have multiple sections of code, each dealing with actions related to a particular context

    Hmmm ... that must be the royal we. I sure don't do that. I tend to break my applications into different *namespaces*. This not only gives cleaner code (and less to mentally chew on) but allows me to play apache tricks (no access control on display and/or results but access control on updates).

    As for Ajax, you can have the same big ball of mud as you do with *normal* cgi - its just cleared the picture for you. The picture was cleared for me when the access control became a biz requirement and became crystal clear when I started using CGI::Application.

    -derby
Re: Encapsulating web client side code in Perl modules?
by dragonchild (Archbishop) on May 07, 2007 at 14:03 UTC
    In Kayuda, we found it helpful to look at this problem slightly differently. You have the server and it exposes a rather generic API. You then have clients that consume that API. Now, you might only write one of these clients (your web client), but by making that separation, life was a lot easier.

    And, Javascript isn't bad, particularly if you are using the Dojo toolkit.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      And, Javascript isn't bad, particularly if you are using the Dojo toolkit.
      Really any good (Prototype, MooTools, JQuery, etc) JS toolkit will make it pretty easy to work with.

      -- More people are killed every year by pigs than by sharks, which shows you how good we are at evaluating risk. -- Bruce Schneier
Re: Encapsulating web client side code in Perl modules?
by CountZero (Bishop) on May 07, 2007 at 16:18 UTC
    Any web-framework worth its salt will have implemented this "context" issue somewhere away from your prying eyes and offer you a clean API where context is automatically taken care of. Catalyst springs to mind as a good example.

    Of course the "context" issue has nothing to do with Perl or Java of AJAX or ..., it is just the way the web works and personally I rather have the context dealt with server side where I can control it rather than on the client's machine where Gods know what may have happened to it.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: Encapsulating web client side code in Perl modules?
by jerlbaum (Sexton) on May 08, 2007 at 15:11 UTC

    The notion that web applications have to respond to more than one context has always struck me as being less-than-optimal. Imagine a typical web form: we tend to use a Perl/CGI program to draw up the form (context 1) and when the user submits the form data some parameter gets checked to see what context we are in, and we accept the form data via the same program (context 2). The first lines of code in the program center around finding out what context it is supposed to be in. Furthermore the program has to have multiple sections of code, each dealing with actions related to a particular context.

    What you describe is the fundamental nature of HTTP and web application development, which has been codified and encapsulated in modules such as CGI::Application.

    In CGI::Application, you designate a particular HTML form parameter to identify the "run mode" of your application. By default this is "rm". So, for example, your run modes might be: "show_form", "submit_data". Those particular run modes are then mapped to Perl functions. (By running through a map, as opposed to just eval-ing a parameter, is that you avoid malicious web requests from running arbitrary code.)

    One thing CGI::Application brings to the table is encapsulation of your web app code into a Perl module, as opposed to a "script". This permits all sorts of reuse and good practices.

    To be clear, the alternative to putting all your various run mode functions into a single file (i.e., Perl module) is having one file per function. This is the approach used by so-called "server page" systems, such as Mason, EmbPerl, JSP, ASP, PHP, etc.

    Some people prefer these types of systems. I do not. In my opinion, a web application is a collection of functions which are closely related. For example, you would not use your "show_form" function separately from the "submit_form" function because the two are operating on a particular form with specific fields and a specific desired behavior. I'd rather have those functions all together in one file for easier management.

    Also, on a more philosophic point, the underlying assumption in server page systems is that the number of functions is equal to the number of "pages" in an application. This is not true. In fact, the number of functions is equal to the number of CONNECTIONS between pages. IOW, you might have one edit form which is used to both edit, and create a record. A server page system would require that you have a big if-then-else block to differentiate an edit from a create function.

    Also, you have functions without any page at all. Consider a delete function which returns the user to the search form with a message. In server page systems that ends up being a file with Perl code and a redirect, as opposed to just outputting the search form function. Ugly.

    With regards to AJAX, the run mode structure is particularly useful. A single page might now have half a dozen run modes for updating various bits. In CGI::Application each of these map to a simple Perl function, making implementation a snap.

    Warmest regards,

    -Jesse-

Re: Encapsulating web client side code in Perl modules?
by mpeters (Chaplain) on May 08, 2007 at 21:50 UTC
    The concept of cooperation between client-side Javascript and server-side Perl where the Javascript is totally encapsulated/hidden within a Perl module strikes me as a promising approach:

    Actually this strikes me as the wrong way to do it. Anytime you try to encapsulate one system into another you have 1 of 2 choices:

    1. Limit your usage to only a subset of the wrapped system's functionality
    2. Make your interface to the wrapped system just as complete and complicated as the wrapped system itself.

    GWT (Google's Java system to have users avoid writing Javascript for AJAX apps) recently ran into problems with users because they needed to do things that were easy in Javascript but that GWT didn't provide an interface for. Now Java programmers using GWT have the option of passing in strings of Javascript that GWT then injects into the pages. Try debugging that if something goes wrong.

    Plus their Java code is now littered with Javascript code. It's the same principle of littering HTML throughout your Perl programs. It was bad in the 90's and it's even worse now.

    we can make the web client more productive without having to write an extensive amount of Javascript as some set of functionality can be provided via Perl modules.

    Why are you so scared of Javascript? It's not the same beast it was in the 90's and can actually be quite pleasant if you're using the right framework (my favorite poison is Prototype).

    Javascript is only going to get more and more important for web technologies. You are really doing yourself a disservice by trying to hide from it.


    -- More people are killed every year by pigs than by sharks, which shows you how good we are at evaluating risk. -- Bruce Schneier
      Javascript OO extension that work with a dollar sign means that you have to be extra careful when embedding JS/HTML inside a Perl script, otherwise perl will try to process the ${'something'} as a perl variable and the JS won't work properly. Are there any recommended solutions to this issue, like a Perl module for communicating with Prototype / Dojo / Mootools applications?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://613916]
Approved by Corion
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (2)
As of 2024-04-25 20:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found