Router vs Dispatcher

Hi guys

What’s the difference between a router and dispatcher class?

Crabby

In a nutshell, a router dissects the HTTP request into it’s constituent parts to figure out what the user is asking for. The dispatcher interprets that information and provides a response.

Hi sunwukung,

Thanks for your reply, so far I got something like this;


class Base_Request_Request
{
	/**
	*
	**/
	private $controller = 'index';
	/**
	*
	**/
	private $action = 'index';
	/**
	*
	**/
	private $params = array();
	/**
	*
	**/
	public function __construct()
	{
		$uri = $_SERVER['REQUEST_URI'];
		
		$parts = explode('/',$uri);
		
		if(count($parts))
		{
			if($parts[1] != '')
			{
				$this->controller = $parts[1];
			}
			
			if(isset($parts[2]) && $parts[2] != '')
			{
				$this->action = $parts[2];
			}
			
			$this->params = array_slice($parts,3);
		}
	}
	/**
	*
	**/
	public function getController()
	{
		return $this->controller;
	}
	/**
	*
	**/
	public function getAction()
	{
		return $this->action;
	}
	/**
	*
	**/
	public function getParams()
	{
		return $this->params;
	}
}

then I guess my dispatcher would use the router class get constituent parts?

Is the router responsible for checking whether the controller and action exist?

Thanks again for you reply

The request object (IMO) would purely deal with the components of the request - i.e: is it an AJAX call, what are the contents of the GET and POST arrays, is there any other user data worth capturing. I would move the “getAction” type methods into the Router - which might also contain methods to map custom URL’s to controllers, either through run time configuration or by loading a config file. This would then invoke the Dispatcher, which would load up the required MVC triad and return a Response.

My bad that was supposed to say class Router, sorry for the confusion.

So is the router class also responsible for checking whether the controller and action exist?

Hmm, I guess so - you’d want to catch any badly formed requests prior to entering the dispatch cycle. Alternatively, you may have a class responsible for locating resources that would catch problems between the router/request and the dispatcher. It depends on how decoupled/focussed you want your classes to be.

My experience is in Zend framework apps - so that no doubt colours my perspective. It’s worth checking the documentation in the various frameworks (Cake, CI, Zend, Symfony) to compare their implementation of these components.

No, it’s the dispatchers job.

If you’re experienced with ZF you should know that the router does NOT check if a module/controller/action exists.

What Zend’s router and the OP’s router do are two different things. Had I wanted to quote Zend’s implementation verbatim, I’d simply have pointed to the manual:

http://framework.zend.com/manual/en/zend.controller.router.html

Zend_Controller_Router_Rewrite is the standard framework router. Routing is the process of taking a URI endpoint (that part of the URI which comes after the base URL) and decomposing it into parameters to determine which module, controller, and action of that controller should receive the request. This values of the module, controller, action and other parameters are packaged into a Zend_Controller_Request_Http object which is then processed by Zend_Controller_Dispatcher_Standard. Routing occurs only once: when the request is initially received and before the first controller is dispatched.

Dispatching is the process of taking the request object, Zend_Controller_Request_Abstract, extracting the module name, controller name, action name, and optional parameters contained in it, and then instantiating a controller and calling an action of that controller.

As I mentioned earlier, it’s worth comparing the implementation in the various frameworks to get a feel for how they’ve done it.
Personally, locating, loading and reporting errors pertaining to the existence of resources sounds like the definition of a new class.

Still, I don’t have masses of experience in this field. Perhaps you could pitch in and give some advice to the OP?

Equally which framework you use - it’s, at least in my opinion, never the job of the router to check if a resource exists.
The routing is far too early to determine the existance as a resource might be virtual and only exist if condition a, b or c is met or something like this (e.g. ACL-based).
The router should only verify the form of the request, get all required information out of it and then let the dispatcher (and e.g. plugins like ACL-checkers) decide what to do with those given informations.
The dispatcher would be obsolete if the router would already do the job or you would have to do the job twice as the dispatcher has to check for resources too to do it’s job correctly.

<edit>
No, you’re absolutely right, my bad.

No - the router should know nothing of the actual controller/action, nor should it try to load them or actually invoke an action. This, unfortunately, is a mistake even widely used frameworks like CodeIgniter have made (Router source), so it’s not always a good idea to check how others are doing it. Another mistake that many URL routers make that irritates me is assuming there will always be a specific key name like “controller” or “action” ([URL=“http://dev.horde.org/routes/”]Horde routes does this, and was the reason I could not use it). The router should be flexible enough to handle anything. All it should do it take a URL string, and match it up to specified named parameters, whatever they are. Then it should just return information about the matched route like the route name and param values. That’s it. Then you can pass those values to a dispatcher, set them back on a request object (ala Zend), or whatever else you want.

Check out the router in AppKernel - it’s the most flexible one I know of:
http://github.com/actridge/AppKernel/blob/master/examples/routes_rest.php

All it does is return an array of parameter names with values from the http method/URL match:
http://github.com/actridge/AppKernel/blob/master/tests/RouterTest.php

Disclaimer: I made AppKernel, modeling it after the routing in Merb (which is now reworked in Rails 3).

My bad, I’m lost.

In my application I name dispatcher a class, which instance detects module and action class with parameters. Then I just call callAction method in front controller with dispatching result as parameters.

Additionally a have another class like “link” helper in symfony, which can produce url based on module, action and parameters. I called this class Router.

Did I mistaken? Is it wrong? How should one call this class instead of router?