[Haskell-cafe] PROPOSAL: Web application interface

Nicolas Pouillard nicolas.pouillard at gmail.com
Sat Jan 23 19:38:18 EST 2010

On Sat, 23 Jan 2010 21:31:47 +0200, Michael Snoyman <michael at snoyman.com> wrote:
> Just as an update, I've made the following changes to my WAI git repo (
> http://github.com/snoyberg/wai):
> * I removed the RequestBody(Class) bits, and replaced them with "IO (Maybe
> ByteString)". This is a good example of tradeoffs versus the enumerator
> approach (see below).

* Are you sure that a strict bytestring is fine here? Can the request body
  be used to upload large data? If so why not use a lazy one, not (only)
  for its laziness but for being a list of chunks that fits well into memory

* I would call ResponseBody a ResponseReceiver given its use and the sigs
  of the methods.

* Why not use sendLazyByteString in sendFile as a default method, this
  will fix your "TODO" since I believe the chunk size would be a good one.

* Maybe a ResponseReceiver Handle instance could be provided. Since it
  requires no data type definition and would make an orphan instance elsewhere.
  Maybe a one for sockets would make sense as well.

> * This might just be bikeshedding, but renamed RequestMethod to Method to
> make names slightly shorter and more consistent.

Good for me

> * I implemented Mark's suggestions of adding support for arbitrary request
> methods and information on HTTP version.


> I've been having some off-list discussions about WAI, and have a few issues
> to bring up. The first is relatively simple: what do we do about consuming
> the entire request body? Do we leave that as a task to the application, or
> should the server ensure that the entire request body is consumed?

Good question, is there something in the HTTP spec about this. I don't think
so, and I think it would make sense to give up early if you consider the
input as garbage.

> Next, I have made the ResponseBodyClass typeclass specifically with the goal
> of allowing optimizations for lazy bytestrings and sending files. The former
> seems far-fetched; the latter provides the ability to use a sendfile system
> call instead of copying the file data into memory. However, in the presence
> of gzip encoding, how useful is this optimization?

It is useful anyway.

> Finally, there is a lot of discussion going on right now about enumerators.
> The question is whether the WAI protocol should use them. There are two
> places where they could replace the current offering: request body and
> response body.
> In my opinion, there is no major difference between the Hyena definition of
> an enumerator and the current response body sendByteString method. The
> former provides two extra features: there's an accumulating parameter passed
> around, and a method for indicating early termination. However, the
> accumulating parameter seems unnecesary to me in general, and when needed we
> can accomplish the same result with MVars. Early termination seems like
> something that would be unusual in the response context, and could be
> handled with exceptions.

IORefs could be sufficient (instead of MVars) but this seems a bit ugly
compared to the accumulator. In the other hand sometimes you don't need
the accumulator and so just pass a dump unit. If we live in IO yes exceptions
could do that. However the point of the Either type is to remind you that
you have two cases to handle.

> For the request body, there is a significant difference. However, I think
> that the current approach (called imperative elsewhere) is more in line with
> how most people would expect to program. At the same time, I believe there
> is no performance issue going either way, and am open to community input.

Why an imperative approach would be more in line when using a purely
functional language?


Nicolas Pouillard

More information about the Haskell-Cafe mailing list