[web-devel] On the state of Haskell web frameworks
Christopher Done
chrisdone at googlemail.com
Sun Sep 19 12:49:57 CEST 2010
For what it's worth, I thought I'd throw a simple web app into the
mix, hpaste.org:
* Address http://hpaste.org/
* Source http://github.com/chrisdone/amelie
The notable thing about this application is it's easy to see all the
requirements ("small libraries"):
1. CGI/FastCGI: I needed a way to talk to the web, I chose
CGI/FastCGI. The CGI library is quite general and small.
2. highlighting-kate: I needed to do syntax highlighting. Notice how
it's just a few lines in an isolated module:
http://github.com/chrisdone/amelie/blob/master/src/Amelie/Highlight.hs
3. Takusen: I needed to talk to a PostgreSQL database to save/read
pastes, just a few lines (for setup) in an isolated module:
http://github.com/chrisdone/amelie/blob/master/src/Amelie/DB.hs
4. ConfigFile: I needed a way to store the service's settings in a
configuration file. Again, just a few lines in an isolated module:
http://github.com/chrisdone/amelie/blob/master/src/Amelie/Config.hs
5. blaze-html/xhtml: I needed a way to build HTML inside my program.
6. formlets: I needed a way to generate and validate forms (e.g. the
paste form).
5 and 6 are used in the HTML module:
http://github.com/chrisdone/amelie/blob/master/src/Amelie/HTML.hs
All of these libraries are perfect, they do one thing and do it well.
I just imported them and they did the work for me. You can see also
how they are modules in themselves, not interdependent as part of some
grand framework. It seems that with good libraries, the architecture
of your web app just designs itself. Personally I've always thought
the "MVC" approach isn't particularly novel and follows naturally from
good design. I'm not saying mine is good design, but without putting
much conscious thought towards it, I've ended up with a DB module
(model), a Pages module (controller) and a HTML module (view). To make
this into the MVC approach, I'd just rename them to Model.hs,
Controller.hs and View.hs.
The things that I had to implement myself are as follows:
7. URI routing:
http://github.com/chrisdone/amelie/blob/master/src/Amelie/Routes.hs
How to receive requests and map that into a page + parameters to that
page (e.g. paste/pid/30196 -> pastePage [("pid","30196")]), how to
*generate* a URL with parameters.
And how to generate a *pretty* URL:
http://github.com/chrisdone/amelie/blob/master/src/Amelie/Links.hs A
URL that maps back to a normal URL (e.g.
http://hpaste.org/30196/half_a_proof is actually rewritten by nginx to
http://hpaste.org/paste/id/30196). I think there probably are quite a
few URI routing libraries out there but I only gave it a cursory
glance.
8. Simple template writing.
http://github.com/chrisdone/amelie/blob/master/src/Amelie/Templates.hs
In fact I found that tibbe already wrote something to do this:
http://hackage.haskell.org/package/template but I didn't end up using
it for some reason. Maybe because everything has to be Text and I
couldn't be bothered littering my code with string conversions all
over the place. Turned out I had to do that anyway. Converting between
String and ByteString and lazy ByteString and now Text is a real pain
but you have to do it because all these different libraries decided to
use a particular type. (At least some let you implement a Stringable
class.) I will probably eventually just replace the templating code
with tibbe's or go the full hog and use HStringTemplate. It's all the
same idea, just more or less engineered.
I'm interested in your thoughts and ideas.
If you have any hpaste-size web applications that you have available
online to read that you can maybe summarise and evaluate in the same
way I have above, maybe that can spark some interesting discussion.
Cheers!
More information about the web-devel
mailing list