Server-Side JavaScript with Rhino and Jetty
I'd like to write server-side code in JavaScript. It just makes good sense. Developers that know JavaScript well are likely not doing much work with servers. All those ports and stuff. I'll take browser bugs instead any day :) Anyway the recent word that Steve Yegge wrote a Rhino on Rails (porting most of Rails to JavaScript) prompted me to look into this further.
The example included in this post is the front end of a server-side framework for writing apps in JavaScript. I used the Rhino JavaScript engine from Mozilla and a pure Java web server called Jetty. Both Rhino and Jetty are used in the long-lived Helma project for server-side JavaScript.
The idea was to send all requests to a single JavaScript function. That is essentially what happens in Rails: everything goes to one dispatcher file. Then the request goes to routing where the URL is inspected and the appropriate controller/action pair is chosen to process the request.
After reading some Rhino, Jetty and Helma examples and source code, I've produced a simple example. You can download the example (1.4 MB including Rhino and Jetty) and try for yourself. Read the README.txt. As long as you have a Java Virtual Machine on your computer (which your Mac does) then you just type the following inside the harmony directory
./server
and look at http://localhost:3000/ to see a congratulations page. That's it. It couldn't get easier. Ahh the success of yet another "hello world".
Talking to a database from inside this example is the other critical step in creating a simple web app framework. That's next.
Update July 11, 2007: In a follow up article added the database into the mix for the full meal deal.
Update October 26, 2007: I completely rewrote the example for this article. The original example code was based on an example from Chris Double's blog which describes how to start Jetty from within the JavaScript running in the Rhino shell. I think this architecture was a bit inside out and would have servlet threading issues. If you are really curious you can download the original example (1.2 MB including Rhino and Jetty).
Comments
Have something to write? Comment on this article.
Jonas,
You could use any of PHP, Perl, Python, Ruby, Lisp, Java, C, etc to generate the response to a GET request. Which of these languages you choose is personal preference based on which language you see being best for the task at hand. There are many developers that see the benefit of writing both client-side and server-side code in the same language. JavaScript is the language in the browser so there is a natural argument that leads to using JavaScript on the server-side also.
In this examples I send all GET requests to a single JavaScript function on the server which acts as a "front door" to the server-side JavaScript application. I know this is how Ruby on Rails operates. Having the server-side scripting language take over processing the request as soon as possible (rather than having apache route the request) means that the script programmer has control early instead of the web-server administrator.
Hi Peter,
have you ever looked at Apache Cocoon flowscript system? It is basically a way to write web applications, server side, in javascript. Using also a lot of nice features like continuations and having the strong power of a complete java xml framework.
Simone
Simone,
I haven't looked at Cocoon in great depth. XML is not my thing. I'm looking for a JavaScript server-side framework written completely in JavaScript. Even JSON for config files. This way everything is potentially sharable with the client. Trimpath exploits this idea.
I like some if the ideas of Helma. I like the "object publishing" concept but the Helma framework is written in Java.
Fortunately I have a bit of time on my hands and have some time to play with writing my own framework based on some ideas in this blog post.
I cannot get this to work on my mac for some reason. I've tried all sorts of things like downloading the latest version of jetty, xbean, etc. Any possible hints?
Chris,
Not sure why the old example didn't work for you. I just uploaded a completely rewritten example. Please give it a try if you are interested.
I played around with writing a Rails-like routing system. Javascript lends itself really well to DSLs (as long as you don't mind the syntax) so it looks like it could turn out well. Here's how you interact with it so far. I'd like to add resources() as a macro to define the conventional RESTful actions, but this is a start.
connect('/info/show', controllers.info.show);
connect('/', controllers.front.index);
The code that supports it just barely works, so it's not worth posting yet. If Harmony had two little changes it would make development so much smoother. 1) A "development" mode where the app.js file is reloaded for each request. 2) print errors to the browser so I don't have to juggle 3 windows.
I managed to hack my way toward these goals, just added
shell.loadFile("app.js");
to the top of processRequest() and did a try..catch around
shell.callGlobalFunction("app", args);
The behaviour is pretty rough but it sure is fun to hack in a lightweight server-side Javascript environment.
The code in this example is bare bones. I have a more developed version of Harmony on my computer. The shell is more complete with FILE macro like C and Ruby have so one file can load others with relative paths to promote modularity. It has development modes and environment config files like Rails does. It does the automatic reload in development mode. I'm still working on how to organize the framework files and the various database adapters. The ORM is the biggest huddle I think. Various deployment strategies also need consideration. It is fun to play with this stuff before it turns into a big framework with twenty thousand lines of code but it really does require a lot of work to get to a stage where it could be used for a real project.
Peter,
If you're up for sharing the more developed version of Harmony, I'd love to play around with it. I've been having second thoughts about building a Rails clone in JS.
I'm interested in making the smallest atom of behavior a resource, each of which responds to GET PUT POST and DELETE. Simplifies the routing problem as well as encouraging best practices. IBM's Project Zero has a similar architecture written in PHP.
I'm still not sure how far one can get while maintaining a direct correspondence between the model layer and the URI namespace, but if it works out it seems like a big boon for simplicity.
The code I'm working on is not ready for public viewing yet. It is still chaotic and very experimental.
I'm doing almost exactly what you suggest with each resource reflected as a URL with REST actions. It isn't MVC in the same way Rails is but there is still separation of the various kinds of code. I think this is a good thing as even Rails now seems repetitive and laborious. It is hard to have imagined writing that when Rails was first released.
Peter,
I've been playing with your setup and ran into an issue.
For some reason, I'm not able to access certain functions such as readFile from within the app() function.
Probably due to my inexperience with java, but everything I've tried won't work.
Any insight into the problem would be helpful!
is there examples for setting up on Vista? or do i need to boot up fedora or debian?
- thanks
Gembion, these directions are for Mac OS X and I think would work on Linux quite easily. I don't know about Windows.
Have something to write? Comment on this article.
feed
Hey Peter!
I am not that JS-"pro", as you are... I know how to program js,python,php,etc. but I have never ever heard of running server side JavaScript. I understand that this is possible with your Jetty and Rhino-Tricks, but why does is make sense to push get requests to a JavaScript function? Why not use php? i am confused
... i will do a little research ;P
Greetz,
J