views:

270

answers:

7

I'm building a site similar to StackOverflow, mostly as a learning exercise, and I'm having difficulty understanding how to decide on the different controllers in the MVC pattern.

What exactly is a controller? What controllers would you use to model a Q&A website similar to SO? I'm using ASP.Net MVC, and I notice the URL pattern is always "/Controller/Action" - but that is definitely not how I'd like the final URLs to look like ("/Question/123" does not fit into that pattern). Is that a consideration?

I know this is actually a mix of several questions ... perhaps what I really need is a good tutorial to understand the basics.

+1  A: 

As far as I know, it's largely preference. I once asked myself the same question, but found that controllers are merely that which brings views and models together to present information in an orderly fashion.

I think you could have a Questions controller, having methods like View, Edit, Create, etc. This seems to make sense, especially for the project - a Q&A site.

Jonathan Sampson
+1  A: 

A lot of folks found this discussion very helpful:

What goes into the “Controller” in “MVC”?

DOK
+1  A: 

The controller in an MVC architecture is responsible for asking the model for data and providing data to the view. The reason to have a controller at all is to maintain de-coupling between the model and the view. It is generally recognized that loose or no coupling between components in an oo system is both desirable and necessary. It supports reusability and encapsulation, and therefore promotes maintainability.

The MVC pattern when utilized in the context of a restful web application will support a controller that processes urls with the something like following format:

/Controller/Action/:id

So to view a single question, say, you would have: /questions/view/123. A great write-up on designing a restful web app (based on deli,li,cious) can be found here.

ennuikiller
The controller tends to be the one that performs actions on the model where the views tend to present domain objects defined by the model. The controller specifically is not there to stand between the view and the model - if it were simply a mediator, then you are talking about the classic 3-tier model and not MVC.
D.Shawley
Does the controller also check information that is entered into a system?
James P.
@D.Shawley - I think you are splitting hairs, but you are right, I didnt mention that the controller updates the model as well as querying it. However, I would say the controller is there to specifically stand between the model and view, since it is quite possible to have the model and view communicate directly. The reason you don't want that is to maintain de-coupling. De-coupling results from implementing a controller (moderator).
ennuikiller
I don't think that I am _splitting hairs_ in this case. There is a very fine line between n-tier and MVC. Take a look at one of the original MVC papers (http://heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf) - "A view is attached to its model (or model part) and gets the data necessary for the presentation from the model by asking question". The view is concerned with presenting a filtered subset of the model. The controller provides the logic to manipulate domain objects defined by the model.
D.Shawley
+1  A: 

The way i look at it is, anything you want to perform actions on or with needs a controller. So for example in Q/A site could bbe something like...

If we build it with the following entities and relations

User

  • has many questions
  • has many answers

Question

  • Belongs to user
  • Has many answers

Answer

  • Belongs to user
  • Belogns to question

Then we can have the following controllers dealing with actions performed on the entities above.

  • UsersController - Deals with Creation Update and Deletion of Users
  • QuestionsController - Deals with Creation Update and Deletion of Questions
  • AnswersController - Deals with Creation Update and Deletion of Answers

Your controllers will most likley have more methods than those mentioned.

The next bit is a bit tricky, as its not JUST models that you want controllers for (and some models you wont want controllers for). If your going to be having a user log in then i would create a sessions controller that deals with loggin in and out.

Try to think of what entities your system will be made up off and write them down. Then of those, think of which ones you shall be performing actions on and with. Then you can think about extra controllers needed such as a sessions controller.

And further note, Models are basically the objects/entities of your system, Controllers perform actions with those entities and Views disyplay the model.

cast01
+2  A: 

Let's break your question in two:

  1. What is the role of Controller in the MVC flavour offered by Monorail and ASP.NET MVC?
  2. How url mappings relate to applicative actions?

My take on 1:

As this type of question lend itself to many religiously answers, I believe that the is no "one way to rule them all". Now in the Monorail and ASP.NET MVC (and also RoR of course), a Controller is simply a collection of Actions. The correct question then is "What is the role of Action"?

In my book (the unwritten Monorail-in-action book ... :) ), the role of the Action is to separate the Domain Model from the presentation, both in terms of data structures, and in concerns. Everything that is specialized to the fact that the interface with the domain is through WEB requests, is the controller's layer responsibility. That includes data binding and transformations, dealing with Authentication (but not authorization), and making decisions for the view templates. So, an action will take parameters from the incoming request (a web is not a Domain concern), bind these to a meaningful data that can be send to the Domain as a Query or Command, in the Domain's language, without no cookies, FORM, QueryString, and other "web stuff". It would also, when viewing data, will transform the domain objects that got returned from the Model, into a View Model, that in the same book mentioned earlier is a model separated from the Domain model, and is in charge of supplying the view-template with all the data and the decision making it needs. So, for eg., the view should not ask if (view.User.IsAdmin) and render an "EDIT" button, but instead the Controller's action will have made this question, and supplied the view with a decision, for the view to ask if (view.ShouldRenderEditButton)

So, the Controllers layer separates WEB concerns from DOMAIN concerns.

As for question no. 2:

The idea of mapping the url as Controller/Action is simply a consequence of taking the "Convention over Configuration" approach. Meaning, it would be easier for developers (and consumers) to work with a schema that is common across different web applications. Having said that, it is not written in stone, and like any Convention, it is a basis for Adaptation. So if you are building a website and the product manager asks for "pretty urls", then you just set up your routing engine accordingly.

Ken Egozi
+3  A: 

In simple words, a controller is a contract/bridge between a model and the view.

Here is the flow:

A controller is used for main request processing logic. If a page has to talk with database, the controller sends a request to the model, model performs its task with db and returns some response or db records back to the controller then controller sends this response to the view.

The below picture explains the process more easily:

alt text

Sarfraz
Where's the picture from?
Blair McMillan
Take a look at http://heim.ifi.uio.no/~trygver/themes/mvc/MVC-2006.gif for a better MVC diagram from one of it's inventors.
D.Shawley
The line between the Model and Controller labelled "data" should really be between the Model and the View. The Controller manipulates the Model and the View observes the Model.
D.Shawley
A: 

A controller forms the system boundary, which is the http interface of your application. It takes a request, triggers processing of the request and returns the result to the client.

You can put all actions belonging to a certain class of domain objects into a single controller. This would lead to the mentioned URL pattern /$controller/$action. I'd suggest to use REST. With REST you think in "resources" instead of "controllers" and "actions". Every resource has a common set of methods, namely DELETE, GET, POST and PUT. These methods are the HTTP verbs. You would have more resource than controllers with the non-REST approach, but the total number of actions would be the same.

In your example one resource would be "questions", which would be a list of all questions. To create a new question, the client would sent a http request like "POST /questions $formdata". A new question object would be created and added to the list. The client would get a redirect to the newly created question "redirect /questions/4128" and then loads it with "GET /question/4128".

REST in short:

  • every resource has a global id (URL)
  • every resource has a common set of methods (DELETE, GET, POST, PUT)
  • a REST application is stateless (no session state between requests)

Benefits:

  • simple
  • unified; easy to understand for new developers, easy to use for client developers
  • usable with multiple clients like browsers, feed aggregators, web services ...
  • REST uses the full power of http with no overhead (compared to SOAP web services)
deamon