Thoughts on a Web ToolKit
I have been doing lots of ‘Web Development’ in C/C++ in the last year.
The current workflow currently isn’t that bad, mostly because we use ClearSilver to do many of the hard parts.
Now, ClearSilver is an okay template language, nothing amazing, but its pretty damn fast, and it works. However, ClearSilver also includes a “CGIKit” API, which tries to handle many of the hard parts of running a writing a CGI in C. I would rate the CGIKit as only mediocre, and I have had to dig through it a couple times to extend things or even figure out what the heck it is doing.
I have been thinking about writing a replacement for the CGIKit portion of the API, and using the Electric Template Language from Garrett.
For the API, I am trying to decide between a Monolithic approach, or a more modular one. A simple question: should the API create the concept of Handlers based on URI prefixes, or should you do that yourself?
For example, if the Toolkit was more Monolithic, you would have an API like this:
pwt_register_handler(”/one”, one_handler_func);
pwt_register_handler(”/two” two_handler_func);pwt_run_handler();
Which would then call the appropriate function handler if the prefix was matched.
On the other hand, a more modular approach would look like this:
if (pwt_prefix_match(pwt, “/one”)) {
one_handler_func(pwt);
}
else if (pwt_prefix_match(pwt, “/two”)) {
two_handler_func(pwt);
}
Now, the second example is more flexible, allowing you to put hacks in as needed, but it means more code is written.
Of course, now you say, if you design the API correctly, you can do both, and easily degrade into the more modular method when you need that control, which isn’t the common case. Right, I have no doubts about that, it just means iterating on the API more before much is finalized, to find those points that need to be able to ‘degrade’.
The other challenge in the API design is that I want it to support a CGI mode, FastCGI Mode, and possibly a native Apache Module Handler Mode. I am pretty sure with some macro-magic that can be done — and hopefully without hurting either method significantly.
Lastly, I am having an internal debate on if it should be pure-C, or use C++. I think several parts could be made easier with C++ — for example you could make you own Classes based off a base PWTHandler and subclass them as needed to your own situation. I believe many C++ ‘libraries’ do correctly have a stigma to them — it is too easy to say, well, i need XYZ, and then just #include boot/foobar.hpp. And now you depend on Boost. C Libraries have a consistent history in open source of working well. While C++ is exactly the opposite for the most part. To people who read my blog, do you care which language it is in? Does either one matter to you?
I have little doubt that all of my goals can be accomplished in straight C, but I think it will end up abusing Macros in ways that I hate to get the lines of code per new handler down to the same number as in C++.
June 4th, 2006 at 11:11 pm
Perhaps it should be C++. People are getting quite used to the Ruby on Rails or Django philosophy of doing things in an object oriented fashion. it would be slick to be able to inherit from a XMLRPC object and have it automatically know how to handle a post, and serialize the replies.
However, I like the modular approach with C. Something like:
app* app = new_app(); pwt *my_xmlrpc_pinger = pwt_new_xmlrpc(my_callback); pwt_register_mount(app, "/ping", my_xmlrpc_pinger); pwt_register_mount(app, "/ping/static_page", pwt_static_page("dummypage")); pwt_run_app(app);Even though the OS will cache the CGIs a C++ based web based application would use more memory than a C based API. Bad if there are a lot of CGIs. A good C library can always be wrapped into a C++ library.
In summary, I’m on the fence. I am voting for the modular approach, whether that is in C or C++ I’m not sure.
June 4th, 2006 at 11:27 pm
Ya, I really want to capture some of the ‘magic’ that many of the newer kits like Ruby on Rails or Django do — it kind of can meke it difficult to use straight C for some of that magic.
I don’t want it to be so directly tied to an SQL DB/object marshling system as Django and RoR seem to be. That should be something you can build on top.
June 5th, 2006 at 6:40 am
You already know my opinion on the C/C++ bit (C++ bad, or at least C++ not much better than C for the part you seem to want it to make easier for you), but as far as the callbacks + a runloop function versus requiring the user to do that, it seems like one can be built atop the other. If you provide the matching code, and let the user run their handlers manually, that leaves that open for them, but you can then build the rest on top of it. Although you should note that for things like fcgi the run loop part is kind of required…
June 5th, 2006 at 8:51 am
I know my opinion probably counts for very little, and my experience with C and C++ webkits is limited. However, I do prefer to work with the example style that Ryan gives.
That said, the http://jose.med.kuleuven.ac.be/wt/Home.fcg way of going about things seems to be quite cool on initial inspection, although a little higher level than I imagine you are aiming for…
Like Ryan says, you can always wrap a C API. Vice versa being rather more complex to do..for obvious reasons.
June 5th, 2006 at 9:53 am
On Wit — It takes the approach of a Widget Toolkit, heavily mixing the presentation with the ‘business logic’, in my experience these type of toolkit designs end up not working so well. I prefer the separate template file, which contains all of your design — the code just sets some variables for it, ala ClearSilver or somewhat how Smarty works in PHP.