When you're making a web app, you frequently need different things to happen at a given URL for HTTP POST requests than happen for HTTP GET requests. I am making a web app in Pylons, and I'm encountering this question.
Is it better to distinguish between POST and GET in my URL dispatcher (Routes) or in my controllers? What factors would make one of these options better than the other?
Would the answer be different if I were using Django? Rails? ASP.NET MVC?
Good code should have clean separation of responsibility therefore the routing/dispatching code should control where I request is sent. This is just good design and shouldn't change because of the language.
A reader of the code can tell just from reading the routing code what is expected and where it will go. If you change your mind later on, you can changing the routing code without touching the controllers.
The controller is then only responsibile for handling the request which makes it simpler, making it easier to understand, have fewer bugs and easier to change.
Related
I want to build a Laravel application which users both web and API parts. The common (and mine as well) question is whether to use separate controllers or not.
There are 2 options:
Separate controllers
Laravel API controller structure?
Use one controller and check the request type (is Ajax, or depending on the request link) and return either JSON or HTML.
Laravel resource controllers for both API and non-API use
Those who have the 1-st opinion doesn't explain the DRY problem solution - web and API controllers would be the same except the return statement (JSON or HTML view). But since most post recommend to separate controllers I suspect I don't understand something about the DRY problem solution.
I don't see any disadvantage of the second method. But people say something like
If you use only one controller, you will end up soon with a messy class with thousands of lines. Not only this is not going to scale well, but it will be hard to work with for you and your teammates.
Please explain me the DRY problem solution for the first approach (separate controllers) and the possible underwater rocks in the second approach (single controller)
Please explain which approach is preferable.
I think this is a great question, and I too am keen to see the responses.
I can see the arguments for both approaches. I however would create and maintain separate controllers, whilst using services to share common logic between the controllers where it is known that this will never change.
For example, if you allow users to upload avatar images. I would put such logic in a service and consume this service in both controllers.
The reason for this approach in my mind, is that the web and API logic may diverge and it would therefore be easier to iterate each without impacting the other.
If this is unlikely, then I would still create separate routes, but point them both at the same controllers, so that if it did change in the future, you can simply re-point the API routes to their own controllers.
I’m looking for a neat way to execute a check to see if there are any messages in an inbox (realtime) in a Grails 2.x application.
I’ve moved away from polling via ajax to websockets, which is great at the point where someone actually sends you the message, but when you change to another screen, the “count” still needs to be initialized.
Can anyone advise on a elegant way of doing this?
Interceptors are not ideal as I need to check across just about all controllers
Filters are not ideal because on some screens with graphs there are many ajax request, the check would be run many times for each request.
I’m wondering if there are any other solutions that I’m not thinking of.. but possibly not.
A filter that disregards the check if a request header indicates an Ajax request would work.
Depending on where you need this "count" you could: In your layout (main.gsp for instance) call a tag library which makes use of a service to fetch the count. That way it's only applied to GSPs where the layout is applied (e.g. not any ajax request).
I'm trying to comprehend the concept behind MVC and URL routing. I understand that it's good to seperate your code, hence MVC, but fail to understand the idea behind the URL router!
Instead of having a lot of rewrite rules in htaccess, I send all traffic to router.php, and in this page I have an array with page urls, and its corresponding PHP controller.
To keep it simple, I just include the controller, where the output finally is generated, however having seen lots of other practices, I'm afraid that im doing something wrong, or bad in some way..
Can someone please enlighten me, how to do a good, but simple URL router? Is it okay just to include the controller, which then generates the output? Perhaps someone has some information that describes the subject in details (something understandable for a beginner)
Thanks in advance
There are lots of ways to do URL routing. Some are client side like with backbone.js, others are server side. Doing it with .htaccess is one way, another is th way you are doing it by having a prerequisite path that is is either a hard path, or a regular expression that you parse and figure out where to send it. None of them are 100% right or 100% wrong, it's all preference, and it sounds like you are doing just fine with a route file.
For more information on how different frameworks do routing you should read over the docs on routing for CodeIgniter, and Symfony frameworks to see 2 different styles of server side routing, and then maybe look at the backbone.js framework for client side routing just to see the similarities and differences.
The router in the MVC concept decides which controller it has to load when a user requests a page. E.g. a user requests example.com/something/very/important, the router would now look for an action which is mapped to this route and execute it. There are different methods how you can accomplish that (simple include, instantiating a class and running a method etc.) but the most simple and still powerful solution I came up with is creating a separate class for every action. I've written a little article on that matter, since I've been asked this question several times, you can have a look at it here: Writing a simple and fast mvc router with PHP
The ASP.NET Routing module is responsible for mapping incoming browser requests to particular MVC controller actions.
Routing is a pattern matching system that monitor the incoming request and figure out what to do with that request. At runtime, Routing engine use the Route table for matching the incoming request's URL pattern against the URL patterns defined in the Route table. You can register one or more URL patterns to the Route table at Application_Start event.
I'm from a non-computing background and I'm struggling to getting my head around MVC design approaches and frameworks in general. I "get" code re-use, and separation of logic from display, and I "get" encapsulation and decoupling, but I don't get this.
At the moment I simply put everything in root, a separate subfolders for images, cfcs, and _includes, all database interaction via cfcs. I do all my processing at the top of the page, then a comment line then display/page layout below that.
Most of the frameworks I have looked at seem to favour a front controller, so my simplistic version of a top controller MVC design would be a subfolder for cfcs, controllers, and views and a big switch statement in index.cfm
<cfif not IsDefined("URL.event")>
<cflocation url="index.cfm?event=home" addtoken="No">
</cfif>
<cfswitch expression="#url.event#">
<cfcase value="home">
<cfinclude template="controllers/home.cfm"/>
<cfinclude template="views/home.cfm"/>
</cfcase>
<cfcase value="about">
<cfinclude template="controllers/about.cfm"/>
<cfinclude template="views/about.cfm"/>
</cfcase>
</cfswitch>
.. but what real advantage does that give me over a page controller design? Unless it's just the kind of sites I write, I always seem to find that the controller logic is specific to a view, its not like one controller could fit several views or several controllers could output to one view, so what would be the point of separating them?
The light hasn't come on for me yet, any pointers?
By "top" controller, I think you mean "front" controller, a single point of entry for requests into an application. As #bpanulla wrote, most ColdFusion frameworks use this design pattern. This becomes particularly interesting with URL rewriting, where it becomes easy to have search engine safe URLs by intercepting the a URL (e.g. domain.ext/i/am/friendly.ext) and routing it to some standard file such as index.cfm while making the requested URL a parameter (often as a request header). This also makes site redesigns where URLs change easier because it lends itself well to aliasing or redirects.
As far as controllers are concerned, they are usually tightly coupled to a particular URL or URL pattern. It's possible be more loosely coupled with controllers, but in practice I find that's an emergent property after multiple refactorings. What should be underlying the controller is one or more calls to a service layer that talks to the database, executes business process, creates stateful entities, etc... Then the controller receives the service layer's outputs and places them into whatever mechanism (e.g. an event object) is used to pass data to the view(s).
It's the service layer that's meant to be reusuable not the controllers. The controllers are merely an extension of whatever framework an application works within. The idea being that you should be able to switch frameworks with very little impact to the views and service layer. The piece that needs to be touched are the controllers.
So a given service object in a service layer should be able to service multiple controllers. For example, consider showing a logged in users' information as a widget on a site. There might be different pages served by different controllers, but each would call the same service object to get logged in user data that presumably might be given to the same view that renders the widget.
Update: Front Controller Advantages
Security: centralized authentication and authorization.
i18n & l10n: inject the right language pack into the request globally
Process Orchestration: think multi step checkout process for a shopping cart where you don't want the back and forward buttons to work - by routing everything through the front controller you're able to enforce what step (i.e. the state)
Logging & Tracking: easily add Google Analytics or other request tracking to a site by making the addition in just one place
Error Handling: centralized behavior
Now many of these items can also be done using <cferror> and Appplication.cfc, but I find it easier to have one centralized point.
Useful Links
http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html
http://msdn.microsoft.com/en-us/library/ff648617.aspx
You actually implemented the crux of Fusebox (http://www.fusebox.org/) with what you wrote. There's nothing wrong with that, and most of the ColdFusion community used something similar to that for many years - Fusebox was the most-used CF framework (in my experience) until just a few years ago when ModelGlue, Mach-II and the other second generation CF frameworks came about.
One thing I can point out is that your approach to controllers (as .cfm files) actually does not enforce encapsulation in the typical OOD fashion, with specific arguments going to an object method call. Unless you are extremely dilligent, over time your .cfm controllers may wind up accumulated a large number of undocumented parameters that alter behavior to solve one problem or another.
With the various frameworks you also get nice features like Application, Session, and Request specific code (onApplicationStart, onRequestEnd, etc). But you can always get those through a simple Application.cfc.
I'm trying to get my head around Cappuccino. I'd like my StackOverview peers to review the architecture below and see if it makes sense - the aim is to utilize the unique benefits of Django and Cappuccino without doubling up where the technologies overlap...
When the web browser requests a 'friendly' URL (eg, /, /articles, etc):
DJango's urls.py matches this to a
view.
The view, rather than doing
DJangos typical work of filling in a
template with the locals dict,
returns the small 'stub' HTML used in
a Cappuccino app directly.
The client receives the Cappuccino HTML
The client requests the Objective J JS
URLs mentioned in the stub HTML
The end-user app is executed and
displayed in the browser
The browser now has a working app. When the user does something that
requests something from the server:
The browser sends an XMLHTTPRequest to a URL.
Django's URLs.py matches this to a
view.
The view does it work, perhaps interacting with the DB model. But instead of returning a template, Django returns some JSON.
The client recieves the JSON, and
does whatever it needs to do.
Does this make sense? We still have the benefit of friendly URLs, and the database being created for us to model our code. However rather than using templates, we're providing Cappuccino stub pages and JSON responses, in order to give users something more like a real app and less like an HTML templating engine.
Is there perhaps a better way of doing things? What do other Pythonistas use? Thanks for your feedback.
For a low traffic site, using Django's routing layer would be fine, but if you plan on getting a significant amount of traffic, you might consider having your proxying webserver handle the stubs.
As for the rest, it works and the TurboGears community has been doing it for years (I was a TG committer so that's what I normally use). The TG architecture of returning a dictionary to a template makes this trivial since you just set 'json' as your template engine.
Doing the same thing in Django isn't much more complicated. Just use the serialization tools to write the result to the response rather than using the templating calls.
Note that when you do an architecture like this, it's considerably easier to manage if you keep all the application logic in one place. Putting some app logic in Django and some in the browser causes things to start getting messy fairly quickly. If you treat your server as a dumb persistence layer (with the exception of validation/authentication/authorization), life is easier.
FWIW, I find Sproutcore to be easier to work with than Cappuccino if you're interested in heavier non-progressive enhancement frameworks.