Thanks for the detailed response. My application essentially has permalink routes that end up rendering the same html as a non-permalink route, but the permalink route does indicate some existing state. Right now it is coded so the permalink route will grab the extra state over a separate JSON request. The problem being that the original html request also gathered the JSON. I suppose my current setup is not truly RESTful and the html response should render the state instead of using an extra JSON call, although I do find this a convenient technique. One way or another I should be able to change things to avoid the extra IO.
Let me start with the theoretical response: if you have both an HTMLOn Thu, Jan 6, 2011 at 5:29 AM, Greg Weber <greg@gregweber.info> wrote:
> lazy and REST seem to go together :)
> Perhaps this will expose my ignorance of laziness/strictness and isn't at
> all Yesod specific. I have a handler that can serve html or json. When an
> html request comes in it still executes the json code. I assume this is
> because the json code uses liftIO. What is the strategy for avoiding
> executing the json code?
and JSON representation for a resource, they should be giving
*exactly* the same data, just in a different format. Therefore, there
should just be a pure function applied to some data to generate the
JSON version, and thus no extra processing should be performed (due to
laziness) when giving an HTML response. Therefore, your problem
doesn't exist ;).
Of course, in theory, theory and practice are the same, but in
practice they're not. Sometimes it *is* necessary to provide slightly
different data, and producing that data will require some IO action.
There are a few approaches:
* What you have right now: run actions for both the HTML and JSON
versions, and let Yesod pick the correct result afterward. This is
slightly inefficient, but easy to program.
* Provide two different resources, one providing only HTML, the other
only JSON. Depending on how different your representations are, this
might make sense.
* If the actions can be run inside the IO monad and don't require a
full Handler monad, there is some tricky stuff you can do involving
enumerators. This is not often necessary.
In theory this is an area where Yesod could provide a nicer interface
for users. In practice, the problem doesn't come up very often, and
therefore I don't have enough experience to know what a good interface
would be. I'd like to hear (even in private) a more detailed
explanation of what you're trying to accomplish here.
Michael