Following up on the previous thread, I've started a github project for some ideas of a web application interface. It's borrowing from both Hyena and Hack, with a few of its own ideas. The project is available at http://github.com/snoyberg/wai, and the Network.Wai module is available at http://github.com/snoyberg/wai/blob/master/Network/Wai.hs. The repository also includes a port of hack-handler-simpleserver, and an incredibly simple webapp to demonstrate usage. I intend to make the demonstration slightly more sophisticated. Finally, the repository is now yet cabalized.

I consider this currently to be a straw-man proposal, intended to highlight the issues of contention that may arise. It would be wonderful is we could get the major players in the Haskell web space to get behind a single WAI.

The entire Network.Wai module right now weighs in at only 74 lines, so I do not consider this to be a heavy-weight proposal. Here as some design notes:

The main complaint against Hack is its lack of an enumerator interface for the request and response body. However, this simply words the complaint incorrectly; I don't think anyone is married to the need of an enumerator. Rather, we want to be able to efficiently handle arbitrarily lengthed content in constant space, without necesarily resorting to unsafeInterleaveIO (ie, lazy I/O).

There are a number of issues with left-fold enumerators IMO. It is basically promoting an inversion of control. This may be often times valuable. However, to make this the *only* interface precludes other use cases. The most basic one I ran into was wanting to interleave with read processes. I do not mean to say that it's impossible to interleave reads in such a manner, but I think it's more natural in the approach advocated by wai.

I consider RequestBody and ResponseBody to be mirroring the CGI protocol. Essentially, each handler (CGI, simpleserver, FastCGI, happstack server, etc) will define data types which instanciate RequestBodyClass and ResponseBodyClass. RequestBodyClass provides a single method, receiveByteString, to extract a chunk of data from the request body. ResponseBodyClass provides (currently) three methods, for sending strict bytestrings, lazy bytestrings, and files. While default implementations are provided for the last two based on the first, implementations can provide more efficient versions of them if desired. For example, sendFile might be replaced by a system call to sendfile.

Let me know your thoughts. I'm purposely leaving out many of my reasons for the decisions I've made for brevity, since this e-mail is long enough as is. I'm happy to answer any questions as to why I went in a certain direction. It's also possible that I simply overlooked a detail.

Michael