Hello, I need to version our modules, to preserve modules for backward capabilities, and custom migrations tasks. Right now project folder structure is:
-fuel
--app
---modules
----v2
-----mycore
------classes (model , and controller folders under this one)
----v3
-----mycore
------classes (model , and controller folders under this one)
In my Controller Code (in a controller folder, under the classes folder), for the sub level v2, I have:
v2
mytest.php
namespace v2\myCore;
class Controller_myTest extends \Fuel\Core\Controller_Rest {//code here get_data(){} for example}
v3
mytest.php
namespace v3\myCore;
class Controller_myTest extends \Fuel\Core\Controller_Rest {// code here get_data(){} for example}
I get "Cannot redeclare class myTest ", if i get rid of the parent namespace, so instead of v3/myCore, use myCore, the call succeeds, but i need these controllers/models with the same name, in different namespace, so to preserve database backward compatibility. I need to use models from v2 and v3 , for example:
The most obvious candidate for that error message is not following the naming rules.
You get it when the url resolves to a classname, and the classname resolves to an existing filename, but that file doesn't contain the expected class. It then isn't marked as loaded, loaded again in a new attempt, and then you have a colision.
If I name it Controller_MyTest , it produces the same error. I understand that _ is preserved to map to / directory separator. Does the name of a controller then need to have a prefix for namespace too, in my case v2,v3?
This will create the modules v2, v3 (which will be invalid as they don't contain the required folders), and two times mycore, of which the second will never be found, since the first always matches.
Assuming you want to version your API, you need to:
Define only this module path:
- /fuel/app/modules
Have this file: /fuel/app/modules/v2/classes/controller/mycore/mytest.php
Which will contain the class: /v2/Mycore/Mytest. This must have a namespace v2 (as that identifies the module) with class Mycore_Mytest, or namespace v2/Mycore and class Mytest.
Withour routing, the URL will be /v2/mycore/mytest/<action>/<params>
Have this file: /fuel/app/modules/v3/classes/controller/mycore/mytest.php
Which will contain the class: /v3/Mycore/Mytest. This must have a namespace v3 (as that identifies the module) with class Mycore_Mytest, or namespace v3/Mycore and class Mytest.
Withour routing, the URL will be /v3/mycore/mytest/<action>/<params>
Thank you for your response and explanation. Before I saw your response, i went with the implementation where versioning occurs as:
mycore
-classes
- v2
-- controller
-- model
- v3
-- controller
-- model
- shared (code accessed by v2 and v3)
Namespace became:
namespace myCore\v2; and namespace myCore\v3; Urls did not change, and no edit on routes. In config, however, I have changed the Controller prefix from Controller_ to v3/Controller_and v2/Controller per config, respectively.
In your opinion, what do you think is a best approach to version the modules ? To have v3/MyCore/ or /MyCore/v3 ?
People have written books about API and versioning. ;-)
The biggest challenge with excplicit versioning is that you have to maintain two or more sets of source. I think currently the best is to either try to keep your API backwards compatible (so avoiding the need for versioning), or use a version request header and deal with it inside your API.
The big challenge is that versioning requires changes and adaptations to your API clients. If you control them, great, then it's not such a big problem. If you don't, it becomes complex. How do you make your clients switch versions? How do you communicate with them? How do you retire versions? What does it mean if you get a versionless request, is that first version or current version? And so on.