The Template Is Not The View

As server-side web developers, we tend to think of our templating system as providing the View layer in a Model-View-Controller architecture. I have recently come to the conclusion that this is an incorrect approach. Instead, we need to think of the HTTP response as the View.

When an HTTP client makes an HTTP request, what does it get in return? It does not receive only the body of the HTTP response. The client receives the body and the headers of the HTTP response. The response as a whole is what the web application delivers as its presentation to the client.

Templating systems, as far as I can tell, deal only with the body of the HTTP response. In practice, the rest of the response is generally handled by the Controller; for example, setting the status, setting cookies, and modifying headers.

Let’s say we accept the idea that the HTTP response is the View (i.e., the presentation that is delivered to the client). If we accept that idea, then for a clean separation of concerns a la SeparatedPresentation, we need to combine both the template work and the header work into their own layer. That layer needs to be completely separated from the Controller and Model.

Thus, anything that deals with the response, including the setting of headers, should be considered the View layer. If you are setting headers in a Controller, you are losing that clean separation of concerns. To remedy this, your Controller needs to hand off to a layer that builds the response on its own; this is the proper place for the tempalting system to be invoked, not the Controller.

In summary: the template is not the View. The response is the View. We should separate our concerns accordingly.

Afterword

If you like the line of thinking presented here, please check out the Action-Domain-Responder refinement of the MVC pattern. It’s still a work-in-progress so be sure to leave your comments and criticism either here on this blog or as a new issue at Github.

Are you stuck with a legacy PHP application? Subscribe to "Modernizing Legacy Applications in PHP" for tips, tools, and techniques that can help you improve your codebase and your work life!

Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

22 thoughts on “The Template Is Not The View

  1. Everyone is always coming up with new extra layers like they are a new idea. I describe MVC as a basis, but no application that wants to be fully separated and highly testable can possibly fit into just those three.

    Lots of frameworks have the ideas of ViewModels / Presenters / Composers (all considered the same thing in their uses by those frameworks) which help build up data for the view itself. This is just one of many layers that people add on top.

    Then you have you service, domain, entity and all sorts of other classes providing different layers as people continue on their mission to make their code fully separated.

    What would you name this new layer?

    Template is usually (in the circles of PHP-land I have traveled) used to describe a series of views. Views are partials (body, layout, header, sidebar, whatever) and template is the lot. Agree with that or not, if template is just the HTTP body then… what is above that handling the headers?

    Do you have any examples too, as otherwise this whole thing feels a bit hand-wavey.

    Maybe some sort of BlogTemplate, and you call showForm()? it calls a presenter, and inspects the http request object to know what format to return stuff in?

    Is this whole idea going to far?

  2. I see the response as the ‘result of what the view produces’. Strictly in server-side PHP frameworks, there may be a lot of overlap of what is ‘response’ and ‘view’, but looking beyond HTTP and PHP, often there is no concept of ‘response’, when there is definitely a view layer, responsible for making sure that the UI stays up to date with the state of the model.

    Despite many (server-side) web frameworks have a little ‘views’ folder that does indeed usually contain just templates, I think that that’s wrong as well 😉

    • > I see the response as the ‘result of what the view produces’.

      I think that’s a fair way of looking at it. However, note that the View layer in most server-side systems produces only the body of the response, and generally does nothing with headers, even when headers are needed. That’s what I’m addressing in the article.

      > looking beyond HTTP and PHP, often there is no concept of ‘response’, when there is definitely a view layer,

      Agreed; my article addresses only the server-side portions of web applications, not the client-side, and not desktop applications.

  3. It’s an interesting subject. I’ve written my own framework on top of the Laravel IoC container and symfony components and it tends very much to the Action Domain Response approach. The controller is responsible for creating the response. In the application instance, which handles the actual request, it fetches the response from the controller and uses a stack builder to add additional headers. Most of the time the response from the controller is just a rendered view / template. But it can also be a json or xml response. The response class is smart enough to know from the data it receives which headers needs to be send.

    If the response needs a cookie or other headers you can simply register a middleware through the application instance which handles just that. In fact I don’t see why you would need another layer for that.

    In my opinion I think you would be adding more complexity to the view. Just make the response class smart enough to know which headers should be served. Additional headers can be added through middlewares.

  4. I don’t often agree with your wars on terminology, but in this case I think I will. I work in my day job for a .NET team and the constant miss use of “razor view” to indicate a template is crippling. Getting people to understand that a view not only can but often *is* something other than a HTML template hydrated with data seems to be much more difficult than it should be. Actually referring to the “view” as the “response” is actually incredibly useful I think, especially since “view” has other meanings within the same problem domain.

  5. This is semantic. The origin of view is in the development of stateful systems. I understand that if youre reading this you probably already know this..Being that the web is traditionally not stateful, the word response may appear more appropriate on its surface, but it is not, because the V in MVx is a construct not an action. Your ‘response’ is no longer that, once it’s in the clients hands. This turns a thouroughfare into a oneway street. May as well just use good old ‘output’ if reductivism is the goal.

    • If I understand you correctly, then I think we may already be in agreement. In the ADR pattern offering, linked at the end of the article, the word “View” is replaced with “Responder” to more accurately capture the semantics of what’s going on.

  6. @pmjones, It’s funny… This coincides strongly with a conversation I had with a colleague earlier today. Let me start by saying that agree with you. 🙂

    The first important point to make is that “MVC” is an abstract concept (as are all patterns). This article is less about MVC and more about a web (HTTP if you prefer) implementation of MVC. That’s an important distinction… So where @Phil Sturgen points out that everybody wants to add layers to “MVC”… I don’t think that people are trying to add layers as much as define the components of each layer in a given context. In this article you are speaking to web developers so the topic is clearly (if not explicitly) within the context of web applications.

    So that said, I do think that the response headers are part of the “view” responsibility of a “MVC” framework that responds to HTTP requests. Where we have to be cautious is to too deeply couple that behavior into the same entities. The entity that composes the full response (headers + body + trailers) is a component of the view the same as the “template” is part of the view. This becomes clearer if we consider an application framework which is _capable_ of responding to HTTP requests as well as other types of requests.

    For example, a framework which exposes entry points, runs business logic based on that entry point and presents the output of that logic *could* be written in a way which allows it to operate on the web or via a CLI or even through a software API. In this case, the “Response” component must behave differently even though the “template” remains the same. The data layout (“Template”) of a JSON response to a CLI request is structured the same as a JSON response to a HTTP request, but the “Response” itself is very different.

    To take that a step further, the incoming request for such an application must be interpreted differently. By the time the business logic receives the parameters, it does not need to know that they originated from the web vs. CLI args in a system with true separation. This can absolutely be categorized as the responsibility of a “controller” … more specifically the “front controller”.

    So while we can accept “response building” as part of the “View” layer we should also be mindful of whether it is appropriate to bundle it into the same “component” or not. The answer is, of course, implementation specific.

    • Thank you @crussell52 for a considerate, detailed, and well-thought-out response. I find very little to argue with here. The only point I’d wish to expand on is this:

      > By the time the business logic receives the parameters, it does not need to know that they originated from the web vs. CLI args in a system with true separation. This can absolutely be categorized as the responsibility of a “controller” … more specifically the “front controller”.

      I completely agree on the first part about the business logic not needing to know the origin of the parameters. Until recently I would have completely agreed on the second part as well, but reading more into things like EBI/ECB/hexagonal has me leaning in the direction that this would be better categorized as part of the Domain layer, so that the core/central/primary application concerns can be completely separated from any framework, or indeed any set of controllers or actions per se. I confess to not knowing EBI very well and so I may be mangling the concepts here, but I *think* I get the general idea is that each Controller (in MVC) or Action (in ADR) or CLI command (in, well, whatever) becomes the port through which a Boundary is invoked, and the View (in MVC) or the Responder (in ADR) is the adapter back through which the application data is returned. (I apologize to EBI experts for any errors in my understanding.)

      • @pmjones, I’m finally circling back to this. I’m not really familiar with EBI. Can you recommend a good starting point for reading up on it?

  7. I’ll start with the disclaimer that I haven’t finished reading your ADR definition paper, but I will say that the more I learn about MVC, the more I think it has little to nothing to do with server-side web applications.

    MVC, as originally envisaged, is not an end-to-end monolithic application pattern, it’s a UI pattern. Within a single UI, you might have dozens or hundreds of models, views and controllers (representing buttons, inputs, various other widgets), but I no longer think you can have one monolithic template/response/whatever and call that a ‘view’ in MVC nomenclature.

    Honestly, I think the biggest upshot of your ADR idea is that it provides us a clean break from what I have come to understand is a bad abstraction. My advice would be to avoid defining ADR in terms of MVC except where absolutely necessary.

  8. I am a bad coder and I have always difficulties with the huge amount of terminologies, layers, abstractions etc. But seen from my limited perspective I tend to agree. The reason is, that a real-life template defines also the content (e.g. by containing content placeholders). In such a case (where the template is more than a design variation) the template represents also business logic. Even on the client-side I would define e.g. CSS code which makes specific parts of HTML code visible/invisible (e.g. by providing on a phone a different content than on a desktop PC) as a de-facto business-logic (at least from the perspective of a website visitor). During the last years I have developed my own adaptive design framework and there the template is clearly not part of the view. The template rendering leads to an often different content delivery and is therefore part of my presenter (I am using the MVP pattern and not MVC which I consider being a misleading term in the state-less world of web-design). The view is simply the passive HTTP input/output manager – that’s it.

  9. […] Exceto que, em retrospecto, não é. Um dos grandes saltos que temos que fazer é perceber que MVC é para a parte de interface de usuário de nossos sistemas, assim como escreveu o Fowler. Nós, no lado do servidor, achamos que a interface de usuário é HTML, CSS e JavaScript, mas não é. Em vez disso, a interface do usuário é HTTP Request HTTP e Response. Em outras palavras, o template não é a View. […]

  10. […] Exceto que, em retrospecto, não é. Um dos grandes saltos que temos que fazer é perceber que MVC é para a parte de interface de usuário de nossos sistemas, assim como escreveu o Fowler. Nós, no lado do servidor, achamos que a interface de usuário é HTML, CSS e JavaScript, mas não é. Em vez disso, a interface do usuário é HTTP Request HTTP e Response. Em outras palavras, o template não é a View. […]

Leave a Reply

Your email address will not be published. Required fields are marked *