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.<br>
<br><div class="gmail_quote">On Thu, Jan 6, 2011 at 1:20 PM, Michael Snoyman <span dir="ltr"><<a href="mailto:michael@snoyman.com">michael@snoyman.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="h5">On Thu, Jan 6, 2011 at 5:29 AM, Greg Weber <<a href="mailto:greg@gregweber.info">greg@gregweber.info</a>> wrote:<br>
> lazy and REST seem to go together :)<br>
> Perhaps this will expose my ignorance of laziness/strictness and isn't at<br>
> all Yesod specific. I have a handler that can serve html or json. When an<br>
> html request comes in it still executes the json code. I assume this is<br>
> because the json code uses liftIO. What is the strategy for avoiding<br>
> executing the json code?<br>
<br>
</div></div>Let me start with the theoretical response: if you have both an HTML<br>
and JSON representation for a resource, they should be giving<br>
*exactly* the same data, just in a different format. Therefore, there<br>
should just be a pure function applied to some data to generate the<br>
JSON version, and thus no extra processing should be performed (due to<br>
laziness) when giving an HTML response. Therefore, your problem<br>
doesn't exist ;).<br>
<br>
Of course, in theory, theory and practice are the same, but in<br>
practice they're not. Sometimes it *is* necessary to provide slightly<br>
different data, and producing that data will require some IO action.<br>
There are a few approaches:<br>
<br>
* What you have right now: run actions for both the HTML and JSON<br>
versions, and let Yesod pick the correct result afterward. This is<br>
slightly inefficient, but easy to program.<br>
* Provide two different resources, one providing only HTML, the other<br>
only JSON. Depending on how different your representations are, this<br>
might make sense.<br>
* If the actions can be run inside the IO monad and don't require a<br>
full Handler monad, there is some tricky stuff you can do involving<br>
enumerators. This is not often necessary.<br>
<br>
In theory this is an area where Yesod could provide a nicer interface<br>
for users. In practice, the problem doesn't come up very often, and<br>
therefore I don't have enough experience to know what a good interface<br>
would be. I'd like to hear (even in private) a more detailed<br>
explanation of what you're trying to accomplish here.<br>
<font color="#888888"><br>
Michael<br>
</font></blockquote></div><br>