How do I put this delicately? I do not think WAI is the way to go.
On the Hackage page of WAI I read: "Provides a common protocol for communication between web aplications and web servers." This means that WAI is a proposed standardized interface intended to sit between server and a web application. There several reasons why I don't like the idea of a standardized interface between the application server and the web application.
First of all, no one will ever agree on this type of interface. Not on the level of abstraction, not on the actual naming of the datatypes, not on the amount of documentation, not on the placement of the parenthesis. I, for example, don't like WAI at all: I do not want be forced to use enumerators for the output, ByteStrings for the input, only 10 predefined response codes, etc.
I am not thrilled about certain aspects of Wai. For example, the Status type names the constructors after their numeric value instead of their more human friendly names. But at the same time, happstack users are not really going to know the difference. If you look at:
you will see that happstack provides it's own combinators for handling the response code -- so the end user won't even see a difference between the normal happstack server and the wai based one.
In a similar vain, being 'forced to use enumerators for the output' is not really a big deal for happstack. Responses are often created by calling toResponse from the ToMessage class:
It is easy to just stick in a call to fromLBS (from lazy bytestring) to convert the existing lazy bytestring classes to use enumerators. (You don't get the fully power of enumerators that way, but it does mean that enumerators don't have to be invasive).
I don't see the bytestring input as being an issue either.. the network libraries are giving us either Strings or ByteStrings, so it seems like a good starting point. Once again, the happstack libraries already provide abstractions so that you can get the processed data in a variety of different formats. The low-level representation is not often seen directly by the end the user.
Secondly, this type of interface will degrade projects like Happstack and Salvia to be mere `back-ends', which they are not. They are both server implementations _and_ interfaces to the programmer. Salvia for example is designed to be a combinator library (not a fixed API) in which some low-level protocol aspects, like keep-alive, http-range support, REST, serving HEAD requests are implemented in the same paradigm as the higher level web controllers. I truly like this idea and this will be totally invalidated by something like WAI of Hack.
I think Wai has a lot to offer to Happstack. As I have demonstrated already, swapping out the lazy I/O server in happstack with Wai is almost not noticeable to the end user. But we get a few nice things 'for free'. The user now has the option of constructing responses that use enumerators instead of only being able to use lazy ByteStrings. And we can get other middleware for free. At present, happstack has it's own private code for supporting compressed output. But with wai, would we get that for free and could have spent the time doing something new instead.
It should also make it easier for non-happstack projects to use happstack things like ServerMonad with out being tied to the happstack lazy I/O server. Seems like there are still a lot of people interested in CGI and shared servers. In happstack-wai the ServerMonad module does not depend on any other happstack specific modules. So we could actually split that into a standalone library that is usuable with any Wai based app. This would allow people to get a taste of happstack with out having to commit to our whole framework.
What I do like to see though, is something like the Ruby Rack interface, which calls itself a "a Ruby Webserver Interface". This is an interface between the actual OS/network and the application server, not an interface between an application server and the web application. Call it WSI not WAI, this subtle difference actually means a lot.
This WSI would just give me file handle/socket and possible a pre-parsed HTTP message, but that is all. A Rack-like interface would allow me to run my Salvia web applications on any backend, like CGI, or in mod_haskell, in the blazingly fast iteratee based Hyena or behind an Apache proxy. But still, the web application is written against Salvia (or the framework you like most) and can piggy bag on all the neat features it supplies.
I am not really clear on what your vision here is. A file handle/socket sounds pretty low-level. CGI passes information differently than a direct HTTP connection. Would you want your application to have to know about those differences and to handle them specifically? In what ways does the Request type in Wai not meet your desire for a pre-parsed HTTP message ? If you wanted to use your app with Hyena, then wouldn't your app need to return an iteratee based response? My apps run unmodified when I stick them behind an Apache proxy.. what does Wai / Rack need to provide?
I think the interesting part of happstack server is what it does to build functions of the type Request -> IO Response. The low-level part where it actually has to talk to a socket and parse something into a Request or send the Response over the network is not a very innovative part of happstack-server. I would much prefer to let a project like hyena focus on that aspect.
Your goals for Salvia are likely different than happstack's and so wai may not be good for you. I just wanted to give you a picture of why the happstack project might be excited by Wai rather than feeling like it is being relegated to a boring backend. If anything I think that is backwards -- Wai is providing the 'backend' and happstack is the frontend. Wai gives us the ability to swap in different backends with no changes to a happstack application. That means we can get out of the business of backends and focus on the parts of happstack that deliver unique value.
- jeremy