I’m currently using URI versioning.
My index.php
file looks something like this:
#declare middleware
$mw_getVersions = //...(extract client app version from header, and api version from URI)
$mw_devAuth = //...
$mw_prodAuth = //...
#set routing and error middleware
$app->addRoutingMiddleware();
$errorMw = $app->addErrorMiddleware(false, false, false);
$errorMw->setDefaultErrorHandler(//...);
#route
$app->group('/api', function($app) use($mw_getVersions, $mw_devAuth, $mw_prodAuth){
//dev api for testing
$app->group('/dev', function($app){
foreach(getAPIFiles('dev') as $file)
include_once($file);
})->add($mw_devAuth);
//production
$app->group('', function($app){
//v1.0
$app->group('/v1.0', function($app){
foreach(getAPIFiles('v1.0') as $file)
include_once($file);
});
//v1.1
$app->group('/v1.1', function($app){
foreach(getAPIFiles('v1.1') as $file)
include_once($file);
});
})->add($mw_prodAuth);
})->add($mw_getVersions);
#run app
$app->run();
where getAPIFiles($version)
returns an array of file paths for the correct api, like ['src/v1.0/controllers.php', 'src/v1.0/datasources.php']
.
I don’t know if this is good practice or not, but it made sense to me so I stuck with it. This means that the client application (in my case a mobile app) needs the api endpoint embedded in its source code. The problem I’m foreseeing with this method is that I don’t have a highly responsive way to control which api the client uses without messing up something down the line.
Is there a way (and would it be considered good practice) to dynamically assign an API version (or at least a set of included files) at runtime, based on the client app version?
For example, by mapping client versions to api version:
$client_to_api_map = ['1.2.5' => 'v1.1',
'1.0.0' => 'v1.0'];
so any client with version in range of 1.0.0
-1.2.4
will be directed to api v1.0
, and anything with 1.2.5
or above would use the new v1.1
api. The problem with this dynamic approach is that I cannot find a way to inject a variable inside the route, like so:
$app->group('/v' . mapClientToApi($request->getAttribute('client_version')), function($app){
foreach(getAPIFiles('/v' . mapClientToApi($request->getAttribute('client_version'))) as $file)
include_once($file);
});
From my understanding, the route is resolved before my $mw_getVersions
middleware has a chance to extract the client version.
Any input or feedback is highly appreciated! Thanks!!