Agavi is a powerful PHP framework that implements the Model/View/Controller (MVC) design pattern that we use in our own blogging application. If you happen to be someone who uses this framework, you might find this tip to be helpful.
Routes and Actions
A key feature of the framework is the ability to map URLs to bodies of executable code on the server. The mapping is referred to as a route, and the code is implemented through an action class. Routes are specified through an XML configuration file that usually specifies the following information:
Concrete Example
Let's add some concreteness to all of these definitions with an example. Suppose you were developing a web service for an rail line that provided endpoints for the following types of things [1]:
For lots of uses, this is probably all well and good. But sometimes you need even more granularity. Take the
Now management has decided that the service should provide more in-depth information to travel agents who have registered with the service. Perhaps such accounts support a different set of input parameters or perform calculations using a different set of business logic.
Agavi supports the notion of role-based access, and actions can be set up to require different kinds of authentication credentials, but packing two different types of interaction into a common action callback can become a tricky mess of conditionals. What else can you do?
One More Level of Hierarchy
Agavi provides one additional layer of hierarchy for actions that allows you to define different (for the lack of a better name) flavors of the same action. From the directory structure standpoint, you go from a path that looks like
to a structure that looks like:
With our example, could define two flavors:
Similar subdirectories would exist in the validate and views directories.
How Do You Create These Things?
Perhaps the simplest way to create a new action with the added hierarchy is to use the "agavi action" command that is usually used to add actions to an existing project. After specifying the module you're adding to, you'll be prompted for an action name. Use a period to denote an action flavor:
[1] -- It may seem strange to American readers that you could possibly make a reservation without purchasing a ticket, but I seem to recall from my travels in Germany some 19 years ago that you could do such things on the DB. I'm using this as my model.
Routes and Actions
A key feature of the framework is the ability to map URLs to bodies of executable code on the server. The mapping is referred to as a route, and the code is implemented through an action class. Routes are specified through an XML configuration file that usually specifies the following information:
- a name for the route
- the URL, perhaps expressed as a regular expression to match
- the action class to be used for handling the route
- what portions of the URL contain request parameter information
Concrete Example
Let's add some concreteness to all of these definitions with an example. Suppose you were developing a web service for an rail line that provided endpoints for the following types of things [1]:
- train schedules
- ticket fares
- get the the timetable of a specific train
- make a reservation between two stations for a given day
- get the ticket fare on a train between two stations
- purchase a ticket for a train between two stations
Trains, Fares). Each bulleted list would map to an individual route that supported both HTTP GET and POST operations, which are implemented in the action classes via separate methods (executeRead() and executeWrite()).For lots of uses, this is probably all well and good. But sometimes you need even more granularity. Take the
Fares module, for example. Suppose we've implemented an action class named Ticket that handles price queries and purchases. Now management has decided that the service should provide more in-depth information to travel agents who have registered with the service. Perhaps such accounts support a different set of input parameters or perform calculations using a different set of business logic.
Agavi supports the notion of role-based access, and actions can be set up to require different kinds of authentication credentials, but packing two different types of interaction into a common action callback can become a tricky mess of conditionals. What else can you do?
One More Level of Hierarchy
Agavi provides one additional layer of hierarchy for actions that allows you to define different (for the lack of a better name) flavors of the same action. From the directory structure standpoint, you go from a path that looks like
SomeModuleName/actions/SomeRouteAction.class.phpto a structure that looks like:
SomeModuleName/actions/SomeRoute/SomeFlavorAction.class.phpConsumer and TravelAgent:Fares/actions/Ticket/ConsumerAction.class.php
Fares/actions/Ticket/TravelAgentAction.class.phpSimilar subdirectories would exist in the validate and views directories.
Fares/validate/Ticket/Consumer.xml
Fares/validate/Ticket/TravelAgent.xmlFares/views/Ticket/ConsumerSuccessView.class.php
Fares/views/Ticket/ConsumerErrorView.class.php
Fares/views/Ticket/TravelAgentSuccessView.class.php
Fares/views/Ticket/TravelAgentErrorView.class.phpHow Do You Create These Things?
Perhaps the simplest way to create a new action with the added hierarchy is to use the "agavi action" command that is usually used to add actions to an existing project. After specifying the module you're adding to, you'll be prompted for an action name. Use a period to denote an action flavor:
Action Name [Index]? Ticket.TravelAgentThis will create the classes with the appropriate naming convention (
All you need to do is add code and add an entry to the
Module_Action_Flavor). All you need to do is add code and add an entry to the
routing.xml configuration file. The dot notation (i.e. Action.Flavor) is used in the action attribute of the route element as well. To ensure that a route is associated with a user having the appropriate credentials add a source attribute to the route element.source="user[credentials][TravelAgent]"[1] -- It may seem strange to American readers that you could possibly make a reservation without purchasing a ticket, but I seem to recall from my travels in Germany some 19 years ago that you could do such things on the DB. I'm using this as my model.































Comments for Agavi Routes with Flavor
Leave a comment