We’ve saved the best for last. For the majority of Yesod handlers, the recommended approach is to load up the database results into memory and then produce the output document based on that. It’s simpler to work with, but more importantly it’s more resilient to exceptions. If there’s a problem loading the data from the database, the user will get a proper 500 response code.
What do I mean by “proper 500 response code”? If you start streaming a response to a client, and encounter an exception halfway through, there’s no way to change the status code; the user will see a 200 response that simply stops in the middle. Not only can this partial content be confusing, but it’s an invalid usage of the HTTP spec.
However, generating the xmlpipe output is a perfect example of the alternative. There are potentially a huge number of documents (the yesodweb.com code handles tens of thousands of these), and documents could easily be several hundred kilobytes. If we take a non-streaming approach, this can lead to huge memory usage and slow response times.
So how exactly do we create a streaming response? As we cover in the WAI chapter, we have a
ResponseSource constructor that
uses a stream of blaze-builder
Builders. From the Yesod side, we can
avoid the normal Yesod response procedure and send a WAI response directly using the
sendWaiResponse function. So there are at least two of the pieces of this
Now we know we want to create a stream of
Builders from some ...