1

I am trying to build an API with Zend_Rest_Route. In my tasks module I have 3 controllers :

  • tasksController
  • typesController
  • statusController

I can access my tasks controller by setting this in my routes.init

routes.qtasks.type = "Zend_Rest_Route"
routes.qtasks.route = "/tasks/:id"
routes.qtasks.defaults.module = "tasks"
routes.qtasks.defaults.controller = "tasks"
routes.qtasks.tasks = "tasks"

routes.tasktypes.type = "Zend_Rest_Route"
routes.tasktypes.route = "tasks/types/:id"
routes.tasks.defaults.module = "tasks"
routes.tasktypes.defaults.controller = "types"
routes.tasktypes.tasks = "types"

However, I can access my tasks/types, tasks/types/1, etc but to access my tasks controller, I have to use the url /tasks/tasks/1 even if I have set the route = "/tasks". I am expected to be able to access it via /tasks/1 Why this doesn't work as expected ? (it works perfectly fine when I used to use it with Zend_Controller_Router_Route_Regex).

Update : I have 4 controllers in my module (some REST, some normal) My REST Controllers (which extend Zend_Rest_Controller so it automaticaly redirect to the correct method) have the standard REST methods (indexAction, getAction, putAction, postAction, deleteAction)

  • TasksController (Zend_Rest_Controller)
  • TypesController (Zend_Rest_Controller)
  • StatusController (Zend_Controller_Action) but simulated as a Rest Controller (see routes.ini)
  • ViewController (Zend_Controller_Action) => manage the different php views associated with phtml

The StatusController is a Zend_Action_Controller because Zend does not seem to manage hierarchical REST url (in this case /tasks/types/:type_id/status/:id). I use my checkhttprequest method to forward to the correct action.

Here is my routes.ini for all that controllers :

; task views
routes.tasksindex.type = "Zend_Controller_Router_Route_Regex"
routes.tasksindex.route = "tasks/view"
routes.tasksindex.defaults.controller = "view"
routes.tasksindex.defaults.module = "tasks"
routes.tasksindex.defaults.action = "index"

routes.tasksviews.type = "Zend_Controller_Router_Route_Regex"
routes.tasksviews.route = "tasks/view/(\d+)"
routes.tasksviews.defaults.controller = "view"
routes.tasksviews.defaults.module = "tasks"
routes.tasksviews.defaults.action = "view"
routes.tasksviews.map.1 = "id"

routes.tasksadmin.type = "Zend_Controller_Router_Route_Regex"
routes.tasksadmin.route = "tasks/admin"
routes.tasksadmin.defaults.controller = "view"
routes.tasksadmin.defaults.module = "tasks"
routes.tasksadmin.defaults.action = "admin"

; tasks REST API
routes.tasks.type = "Zend_Rest_Route"
routes.tasks.route = "tasks/:id"
routes.tasks.defaults.module = "tasks"
routes.tasks.defaults.controller = "tasks"
routes.tasks.tasks = "tasks"

; task types REST API
routes.tasktypes.type = "Zend_Rest_Route"
routes.tasktypes.route = "tasks/types/:id"
routes.tasktypes.defaults.module = "tasks"
routes.tasktypes.defaults.controller = "types"
routes.tasktypes.tasks = "types"

; task type status Simulated REST API
routes.taskstypestatus.type = "Zend_Controller_Router_Route_Regex"
routes.taskstypestatus.route = "tasks/types/(\d+)/status/?([0-9]+)?"
routes.taskstypestatus.defaults.controller = "status"
routes.taskstypestatus.defaults.module = "tasks"
routes.taskstypestatus.defaults.action = "checkhttprequest"
routes.taskstypestatus.map.1 = "type_id"
routes.taskstypestatus.map.2 = "id"

Note : /the TypesController.php and StatusController.php work. I only have an issue with the TasksController which I want to be accessible as http://demo.localhost/tasks and not http://demo.localhost/tasks/tasks/

Olivier
  • 3,121
  • 2
  • 20
  • 28

3 Answers3

0

Is it possible to replace both blocks of route with something like:

routes.tasks.type = "Zend_Rest_Route"
routes.tasks.route = "/tasks/:controller/:id"
routes.tasks.defaults.controller = tasks
routes.tasks.defaults.module = tasks
routes.tasks.defaults.id =

You set a default for the /:id param to null so if the param is not set the route is still triggered.

Remko
  • 968
  • 6
  • 19
  • This does not work. I also tried to put a default controler but I have this error "Invalid controller specified (index) module name (tasks) action name (index)" with the url http://demo.localhost/tasks/ (but http://quimeo.localhost/tasks/tasks still works) – Olivier Jul 31 '13 at 14:52
  • What actions do you have in your controller (and what is the default action?) – Remko Jul 31 '13 at 15:03
  • Unfortunately this does not work :( I have updated my question with more information on my controllers and routes.ini – Olivier Jul 31 '13 at 15:51
  • Are the routes 'fixed' or is it possible to rewrite the used routes? You're kinda stuck this way. – Remko Jul 31 '13 at 16:12
  • What do you mean by fixed? I can make changes if that makes it work :) – Olivier Jul 31 '13 at 17:30
0

This line looks suspicious:

routes.qtasks.tasks = "tasks"

Did you mean:

routes.qtasks.action = "tasks"

or:

routes.qtasks.defaults.tasks = "tasks"

You probably need to set the default value for the id param too.

takeshin
  • 49,108
  • 32
  • 120
  • 164
  • I found this in the documentation (http://framework.zend.com/manual/1.12/fr/zend.controller.router.html#zend.controller.router.routes.rest and in a tutorial http://breerly.com/blog/2010/10/21/restful-routes-with-zendrestroute-and-zendconfigini/) where it says to add routes.rest.mod = project,user where mod is the module (Mod_ProjectController, etc) . If I don't add this (especially the routes.tasktypes.tasks = "types", my url http://demo.localhost/tasks/types/1 does not work I give me a "Action "1" does not exist and was not trapped in __call() – Olivier Jul 31 '13 at 16:04
  • I have put a default id. Now, this is strange. The url http://demo.localhost/tasks works as it redirects to TasksController in Tasks module action indexAction (http://demo.localhost/tasks/tasks also still works but I guess this is normal) but http://demo.localhost/tasks/14 does not work (http://demo.localhost/tasks/tasks/14 still works) – Olivier Jul 31 '13 at 16:08
0

It seems like Zend requires the route to be named 'rest', and modules like properties along with their controllers as values. For example:

routes.rest.type = Zend_Rest_Route
routes.rest.tasks = tasks,types

This way, Tasks_TasksController and Tasks_TypesController will be REST APIs.

Check carefully the documentation.

Jose Arandi
  • 178
  • 2
  • 5