iam using zend framework to build a REST web service and i am using modules to separate my api versions, as i have mentioned here
Ex: "applications/modules/v1/controllers", "applications/modules/v2/controllers" have different set of actions and functionality. I have mentioned my default module as "v1" in my application.ini
I am using context switching along with Regex Routing as i have mentioned here in my accepted solution:
$router->addRoute(
'route1',
new Zend_Controller_Router_Route_Regex(
'api/([^-]*)/([^-]*)\.([^-]*)',
array(
'controller' => 'index',
'action' => 'index'),
array(
1 => 'module',
2 => 'controller',
3 => 'format'
)
));
This is my url: http://localhost/api/v1/tags.xml
"v1" indicates module. Now, coming to context switching, if the url has v1, it is going to v1 module's TagsController. But if the module in url is v2, i am getting an error such as:
The requested URL
/pt/public/index.php/api/v2/tags.xml
was not found on this server.
I could not understand why its blowing up. Is it because i have put the default module as v1? I am not able to change the module based on the url.
And this is my directory tree:
application
modules
v1
controllers
TagsController.php
v2
controllers
TagsController.php
library
My goodness... i have figured out the solution... the controller class name in the v2 module must be "V2_TagsController", not just "TagsController". Thank God, it is working now :)
See the class names for controllers below:
- application
- modules
- v1
- controllers
- TagsController.php (class TagsController)
- v2
- controllers
- TagsController.php (class V2_TagsController)
- library
Related
Good day.
I've just started learning ZF2, replicated the Album example step-by-step, and then decided to make it a bit more interesting by adding user registration, and then make the two work together in some way, so i added a new 'Auth' module.
So, when i only had one module in the module list (aside from the Application module) in application.config.php, it was all fine, but when i added the Auth module to the list like so:
'modules' => array('Application', 'Album','Auth',)
i got the following error when trying to access any views from the album module which was working absolutely fine prior to this change:
Zend\View\Renderer\PhpRenderer::render: Unable to render template "album/album/index"; resolver could not resolve to a file
But when i changed the order in which the modules are presented in this array like so:
'modules' => array('Application', 'Auth','Album',)
not a single view (and it has only one) from the Auth module could be rendered, while the Album module was fine.
Zend\View\Renderer\PhpRenderer::render: Unable to render template "auth/user/index"; resolver could not resolve to a file
Both of these views exist at these locations, but the renderer doesn't see them for some reason.
You can see the project's contents here.
Thank you for any tips in advance.
Looks like you copy pasted the the view manager config for Auth module.config.php.
This should be auth rather than album for your templates to work correctly.
'view_manager' => array(
'template_path_stack' => array(
'auth' => __DIR__ . '/../view',
),
),
I'm trying to define RESTful routes for sub directory controllers. I want to be able to create routes for the url at admin/questions/*. My controller is Admin_QuestionsController:
- application
- controllers
-Admin
QuestionsController.php (class Admin_QuestionsController)
Below is how I'm declaring my RESTful route for this controller:
$restRoute = new Zend_Rest_Route($front, array(), array(
'admin' => array('questions')
));
$router->addRoute('rest', $restRoute);
..from the documentation I can't see what I'm doing wrong - http://framework.zend.com/manual/1.12/en/zend.controller.router.html#zend.controller.router.routes.rest. However, I get the following error:
Invalid controller specified (admin)
I can get the routes to work when I declare then not as Rest routes:
$router->addRoute('admin_questions',
new Zend_Controller_Router_Route( '/admin/questions', array(
'controller' => 'Admin_Questions',
'action' => 'index')
)
);
..so I don't think I've have the folder structure wrong, or the class name. But, I need RESTful routes which I'm unable to achieve.
The Zend_Rest_Route route like you have defined, works if you have Zend modules enabled. The documentation mentions "translating the HTTP method and the URI to a module, controller and action". To enable modules, add the following two lines in your application.ini:
resources.modules[] =
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
Then create a directory in application/modules named admin/controllers, and create your QuestionsController in application/modules/admin/controllers/QuestionsController.php.
The rest of your application should (hopefully) still work as the default module.
i'm a beginner with zend framework2,
i followed two tutorial on how to build module, followed instruction step by step, but when finished i have a blank page on my browser!!
one of my tutorials is:Zend Framework 2.0 by Example(creating user module)
what should that according to??
'Module (Users) could not be initialized.'
As you mentioned in your comment it could be the problem of missing module(Users) name in application.config.php which is located under config folder.
return array (
'modules' => array(
'Application', 'Users' //<== mentioned your module name here
),
....
);
--SJ
So I want to add backward in-compatible changes to my API.
I was thinking of doing the following.
All of my api endpoints are accessed as follows:
/v2/account
/v2/order
Having a v2 controller that is passed an API version and calls the appropriate function in version specific controllers that are subclass to v2.
so for version 2013_02_13 it calls v2_2013_02_13::account for account api call
How would you implement an API versioning system to support backward incompatible changes using a PHP mvc framework?
In Kohana you could just use a directory for that. So your controllers would be placed like this.
application/classes/Controllers/V2_2013_02_13/Enpoint1Controller
Than you can set up routes for your different versions.
Route::set('v2', 'v2/<controller>(/<action>)')
->defaults(array(
'directory' => 'V2_2013_02_13',
'controller' => 'welcome',
'action' => 'index',
));
This would be the most easy approach, however if you really want to have some dynamic way to call specific versions of your controllers than I would look at the HMVC of Kohana.
My guess would be, that you need an entry controller for each version you have and do an internal request to the correct controller.
Maybe something like this.
Route:
Route::set('versioned', '<version>/<someAction>')
->defaults(array(
'version' => 'v2',
'someAction' => 'user'
'controller' => 'welcome',
'action' => 'index',
));
Controller:
class Controller_Welcome extends Controller {
public function action_index()
{
// Your Version and the action
$this->request->param('version');
$this->request->param('someAction');
// Do an internal request to the right controller (the v2/user is an example)
$internalRequest = Request::factory('v2/user');
}
}
I hope this helps.
I've created a multimodule application using phalconphp developer tool:
phalcon project <projectname> module
And I've added a backend module (the frontend is generated). Now I would like all backend routing do the following:
$route->add('/admin/:controller/:action/:param', array(
'module' => 'backend',
'controller' => 1,
'action' => 2,
'params' => 3,
));
But my routing also defines:
$router->setDefaultModule("frontend");
$router->setDefaultNamespace("Groendesign\Backend\Controllers");
And therefor when I browse to: http://myprojectname/admin it searches in my backend module for the frontend Namespaces, How should I proceed with this?
What I want to achieve is that every url that has the prefix /admin/ is send to the backend module. Using the url to define which controller, action and parameters.
I've fixed this by removing the setDefaultNamespace from my bootstrap and adding it to the Modules.php file in each Module. Thereby setting the DefaultNamespace only in the correct module.