Skip to content

Instantly share code, notes, and snippets.

@wells
Created April 6, 2016 17:05
Show Gist options
  • Save wells/53739a4c9676e22e59821bc420a2b92b to your computer and use it in GitHub Desktop.
Save wells/53739a4c9676e22e59821bc420a2b92b to your computer and use it in GitHub Desktop.
API Versioning in Laravel AppServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
// Bind versioned API resources to their interfaces
$namespace = 'Wells\\Project\\';
// These are mere examples
$resources = [
'Posts',
'Users',
];
$services = [];
foreach ($resources as $resource) {
$services[$namespace.$resource] =
$this->mapVersion($namespace, $resource);
}
foreach ($services as $key => $value) {
$this->app->bindIf($key, $value);
}
}
protected function mapVersion($namespace, $resource)
{
// Retrieve the Accept header from the Request
$mimeType = request()->server('HTTP_ACCEPT', '*/*');
// Try to load the requested version, if provided
$version = $this->parseMimeType($mimeType);
$classPath = $version ?
$this->formatPath($namespace, $version, $resource) : null;
// Requested version exists for this resource
if ($classPath && class_exists($classPath)) {
return $classPath;
}
// Map the latest version of the resource
$versions = (array) config('project.api_versions', [1.0, ]);
// Reverse sort of the API versions
rsort($versions);
// Find the latest version of this resource
foreach ($versions as $version) {
// Convert to underscore format (i.e. V1, V1_1, etc)
$version = $this->formatVersion($version);
$classPath = $this->formatPath(
$namespace, $version, $resource
);
if (class_exists($classPath)) {
break;
}
}
return $classPath;
}
protected function parseMimeType($mimeType)
{
// Break up the mime type by semicolon
$mimeParts = (array) array_filter(
explode(';', $mimeType), 'strlen'
);
foreach ($mimeParts as $part) {
if (starts_with(trim($part), 'version=')) {
// Remove version= from string
$version = str_replace('version=', '', $part);
// Convert to underscore format (i.e. V1, V1_1, etc)
$version = $this->formatVersion($version);
return $version;
}
}
return null;
}
protected function formatPath($namespace, $version, $resource) {
return $namespace.'V'.$version.'\\'.$resource;
}
protected function formatVersion($version)
{
return str_replace('.', '_', (double) $version);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment