Meus 2 cents:
Respondendo a pergunta especifica: como manter o codigo de cada versao (v1, v2, etc) ?
Quando tive essa necessidade, foi mantendo como voce comentou: uma pasta para cada versao especifica e o roteador (p.ex.SLIM) apontado para ela, usando o "use v1/crud as crudV1; use v2/crud as crudV2" para identificar as funcoes desejadas, usando um namespace diferente para cada uma.
|-api
|-v1
- crud da v1
|-v2
- crud da v2
Exemplos de namespace neste caso na propria documentacao do PHP: Defining multiple namespaces
Semelhante ao caminho apontado pelo @silvestrini no outro comentario.