7

I'm learning to implement RESTful APIs, and the concepts of Controller and Router are common in many frameworks, along with the MVC pattern in general, so I'm encountering them everywhere.

From this question and googling around I understand that they are not the same thing, as they are responsible of very specific, and different, actions. But one thing isn't clear: design-wise, is the router considered part of the controller?

In the mentioned question, one user comments:

You only need a model (database), a controller (which is the router), and the view (a page). That's it. If you have a Router and a Controller then you've over complicated it and are just using the Router to pass data to a Controller. A Controller is a Router, but a Router is not a Controller.

I often see routers and controllers on the same file, but it's very common to separate them in different files and/or directories. From this I understand that they are intimately related, but sometimes it's better to separate them to implement separation of responsibilities, and to make our codebase modular and easier to maintain.

Also in the mentioned question, we can see answers considering the router part of the controller layer, but others treating it as a different entities. Both can make sense in a thought experiment:

  • Maybe you consider the router to exist before the MVC, as in one MVC per page. The router maps to the controller, but it's not considered part of the controller itself.
  • Maybe you consider the router to be part of the controller, as in the whole webpage is one monolithic implementation of MVC. The router maps to the controller because one is part of the other.

This scenario is very subjective, but in the context of software architecture and design, is the MVC pattern more specific or clear about the roles and structure of routers and controllers?

In other words, is the router a module inside the controller, or is the router considered a separate actor (MVCR perhaps)?

4 Answers 4

8

How to you write the word "computer" in ancient latin language? Nobody knows, because for sure, there were no computers in the roman empire ;-)

The MVC architectural model was designed in the 70s to address a clean separation of responsibility and decoupling the "application" logic (Model) from the user interface (Views for the display, Controller for the input).

When we come to distributed architectures, we have a couple more concerns to add to our architectural design. Since routing was obviously not relevant in early MVC, you have the choice:

  • Stick to the MVC concept with some interpretation: in this regard, routing is indeed closer to the C than to anything else;
  • Shift to a web-contemporary MVP architecture, in which the P takes a central role of being not only a (distributed) controller but also playing the role of a middleperson between M and V. In this context, the router is without hesitation part of the P.
  • Or use any other architecture model that better expresses the needs. "MVCR" has the advantage of being less artificial than MVC, but has the inconvenience, that there's no literature about how R should relate to the others. And don't forget that you're not limited to MVxxx - you may as well consider a Clean Architecture and similar
6

Your question is rife with "if A then B" and "A XOR B" suppositions, where there is no logical connection between A and B.

It's so persistently present in your question that it pretty much invalidates or otherwise distracts from the arguments you're trying to make.

Don't get me wrong, it's good that you're trying to learn and critically think about what you are learning. The problem here is that the question you're asking isn't the issue, it's the incorrect basis on which your question is grounded.

This answer mostly addresses those incorrect suppositions, which will hopefully steer your understanding of the terms you use in your question, which in turn should help in understanding why the way you're thinking about certain things just isn't quite right.


"Are they considered separate entities" is always a matter of scope.

As a backend developer, I generally speak about "the frontend" as if it were one entity. It's not, and I know it isn't, but from my position there's no point in distinguishing between the individual components of something I don't work with.

To someone looking at MVC close up, the router and controller are two very separate entities. To someone looking at MVC as "the presentation layer", they'll generally not bother to distinguish between them as entities.

This is very important to remember when you're using things like comments posted online as a reference source. If the thread isn't focusing on MVC up close, the comments you read are more likely to lump the presentation logic into a single indistinguishable blob - even though it isn't - because there's no benefit to making that distinction then and there.

As an aside, "entity" itself is already poorly defined. In OOP terms, it generally equates to "non-data-only class", but even that definition is up for grabs.


I understand that they are not the same thing, as they are responsible of very specific, and different, actions. But one thing isn't clear: design-wise, is the router considered part of the controller?

SRP dictates that classes should have only one responsibility. Understanding that controllers and routers have specifically different responsibilities should raise a flag that in any clean codebase they would be separated into separate classes.


In the mentioned question, one user comments: "You only need a model (database), a controller (which is the router), and the view (a page). That's it."

Well, no. The business and persistence layers (or if you prefer DDD: Domain, Application and Infrastructure layers) are notably missing here, among others.

This comment is so excessively and naively oversimplified that, when taken at face value, it is advocating for something that is widely agreed to be bad practice. In this proposed system, you'd be accessing the database directly from the controller, as there would only be a database/controller/view, right? What about permission/authorization logic? Well, since it's logic, it should be directly implemented into the controller then, since there's no other place to put it. Since there isn't even a (MVC) model in this proposed system, how are we getting that data from the database to the view?

If that doesn't raise some red flags, then you've got significantly bigger fish to fry than the question you posted here.


we can see answers considering the router part of the controller layer, but others treating it as a different entities

"Are they separate entities" and "Are they on separate layers" are not the same question.

What you stated here isn't a contradiction. They're in the same layer, but they're not mashed into a single entity. That just means that this layer has more than one entity - which applies to pretty much every code layer I've ever come across.


Maybe you consider the router to exist before the MVC, as in one MVC per page.

MVC is generally taken to mean the architectural approach to separating your presentation logic into controllers, models and view. MVC is not a countable unit of "one specific controller, one specific model, and one specific view".

Maybe you consider the router to be part of the controller, as in the whole webpage is one monolithic implementation of MVC. The router maps to the controller because one is part of the other.

"the whole webpage is one monolithic implementation of MVC" sums up what I just said. But the second sentence is in no way related or a logical consequence of the first sentence.

Be very careful about what you mean with "maps to". It expresses a one-way projection, e.g. I would say that a (data) entity maps to a DTO, but that is not the same relationship as exists between a router and a controller.

A route maps to a specific controller action, but that's not the same as a router mapping to a controller.


In other words, is the router a module inside the controller, or is the router considered a separate actor (MVCR perhaps)?

Again, these are not two distinct options.

You've completely glossed over the possibility of having two separate classes each with a distinct responsibility (therefore respecting SRP) using composition to connect one to the other.

The fact that such classes would use composition does not somehow "make them the same entity". That's a completely unrelated consideration.


MVCR perhaps?

MVC does not imply that the code only contains models, views and controllers. "MVC" is not an all-inclusive list of every kind of component in your codebase.


in the context of software architecture and design, is the MVC pattern more specific or clear about the roles and structure of routers and controllers?

You've got to separate the route from the router.

  • The route is invariably tied to the specific controller actions it routes to.
  • The router is a piece of reusable logic that connects an incoming web request to the appropriate controller action/route it belongs to.

The router being reusable logic indicates that it's ripe for abstracting into a class of its own. There'd be nothing to gain from rewriting all that logic for every controller you create.

That being said, specific implementation details are generally left up to the framework itself, and there are several MVC frameworks to choose from.

I can't exclude the possibility that there exists some MVC framework where the routing is done via boilerplated logic inside the controller. I'd very strongly question the quality of the framework, but I can't exclude the possibility of it existing.

I don't know all MVC frameworks by heart, and I don't think that's really the point of your question to begin with - since you're asking about the general concept of MVC rather than a specific framework.

2
  • 4
    I agree. When Trygve Reenskaug wrote up the MVC architecture in 1977, he most certainly did not specify in detail how to implement it for a ReSTful web service, not the least because the web would only be invented 15 years later. While the architecture is technology-neutral, the writeup is in the context of Smalltalk, and e.g. they would have considered handling raw mouse clicks as part of the controller's responsibilities, and there was no database because in Smalltalk, objects can be persisted and resumed at will. You have to adapt the architecture to the technology, and the router is simply Oct 6, 2020 at 10:24
  • 3
    … part of that adaptation. Oct 6, 2020 at 10:24
4

When it comes to distributed 3-tier/n-tier/MVC architectures, routing is part of what's often called the controller layer.

However, within that controller layer, it is a responsibility that can be easily separated out and largely reused. If and how this separation happens is implementation-defined. Some frameworks provide declarative routing, like Spring, and some frameworks provide programmable routing, like Go http. So, if and how much routing you see in the actual controller does not really depend whether you use a multi-tier architecture but rather on the actual framework used.

1

The Router is the dispatch mechanism for the Controller. As such, you can see it as either a convenience controller boilerplate, or as a separate entity, so your MVCR assumption is correct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.