Hi again, FIRST:
Your Controller Code looks good. I would use build-in functionality whenever possible. In this case, using $c->res->content_type instead of setting the content type by hand. But your code should work just fine. Your are right. You have to set the headers before using $c->res->print (or write). But this does not mean that you have to do this in the model. You can set the headers in your Controller before running the model code. SECOND: IMO you are right about your concerns regarding the MVC architecture. The Model should provide the data and not deal with HTTP responses. On the other hand, the data has to be provided in some format. XML is a well known standard format for textual data presentation. Providing the data as XML is as good or as bad as providing the data as DBIC objects. (Well, not really. But close enough for this explanation). The cleanest (most MVC conform) way to do this would be to fetch the raw data from your model and create your XML in a special view. There are several ways to do this. You can create XML using a TT view. ( I have done this before, it works fine). Or you can use existing XML views like Catalyst::View::XML::Generator or Catalyst::View::XML::Hash::LX. (I have not used any of them, but the names are promising). I guess there are even more ways to do it... In your Case, you already have a Model which provides the XML Data (which is fine, as I said before). IMO, one of the great things about Catalyst is that it allows you to get the job done quickly. It makes reusing existing code easy. There is no reason to abandon your existing XML-creation code just because it doesn't fit the MVC layout. Doing so would be contra-productive. So, what can be done to re-use your XML Model and still fit into the MVC architecture? I see two ways: The first one would be to update your model that it writes its data to any IO::Handle compatible object. You can pass $c->res to your Model, which is IO::Handle compatible. Your model uses a Catalyst independent API to write out the data. Catalyst streams the data to the client. Your Model Code is still Catalyst independent and does not know that it is writing to a Catalyst::Response object. No tight coupling. You can reuse your model in non-catalyst applications and easily test its functionality using Test::More or any other test suite. ( I think this is more or less the way proposed by Neil) The second way (which I would prefer, since it is even more MVC conform) is the following: Update your Model to return an IO::Handle-style object instead of a string. You can fetch this object from the model in your controller, and pass it to $c->res->body. Catalyst will take care of streaming the data to the client in small chunks. You don't have to pass any Catalyst related objects to the model anymore. Your model returns the data as a well known standard object which happens to be suitable for streaming large amounts data with catalyst. No tight coupling at all. Problem solved. Have a Tea and celebrate. This is my opinion on this topic. I hope it helps you to find a way which fits your needs, and reduces your confusion about Models, Views and controllers in this specific case. Lukas _______________________________________________ List: [email protected] Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/[email protected]/ Dev site: http://dev.catalyst.perl.org/
