Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Sub-Namespace/Sub-Module Question
  • 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}

    in config.php: 

    I have 

       'module_paths' => array(
            APPPATH.'modules'.DS,
            APPPATH.'modules'.DS.'v2'.DS,
    APPPATH.'modules'.DS.'v3'.DS,
        ),

    And when i call: 


    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: 

    $oldData = v2/myCore/Model_SomeModel::get_old_data(); 
    $newData = v3/myCore/Model_SomeModel::convert_to_new($oldData);   

    Please help, on how can i achieve the folder structure mentioned above. 

    Thank you 
  • Also i could see that this class gets auto loaded twice, in init_class function of autoloader.php 
  • Exact error: 

    ErrorException [ Compile Error ]:
    Cannot redeclare class v3\myCore\Controller_myTest


  • 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.

  • Controller named :

    Controller_myTest, file: mytest.php under the controller folder

    How should I then named the controller ?
  • 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?
  • HarroHarro
    Accepted Answer
    You have mutliple problems.

    You have:
    - /fuel/app/modules/v2/mycore/classes/controller/mytest.php 
    - /fuel/app/modules/v3/mycore/classes/controller/mytest.php 

    You define you have modules at:
    - /fuel/app/modules
    - /fuel/app/modules/v2
    - /fuel/app/modules/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 ?   

  • HarroHarro
    Accepted Answer
    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.

    I can advise you to have a look at ex-Fuel dev Phil Sturgeon's work on API's: https://apisyouwonthate.com. Especially https://blog.apisyouwonthate.com/api-versioning-has-no-right-way-f3c75457c0b7 ;-)
  • Harry thank you for the provided answer and resources 

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion