После некоторых комментариев я создаю вопрос на CodeReview .
Я хочу создать RESTful API с Apache / PHP и Slim Framework (3.x).API должен поддерживать управление версиями на основе URI, например <host>/rest/api/v1/<resource>
и <host>/rest/api/latest/<resource>
.
В целом я нашел решение, которое работает, но я не очень доволен своим решением и хочу знать, что можно сделатьлучше.Я новичок / новичок о Слиме.Я ищу новые идеи и как я могу улучшить свои знания о Slim.
- Общие улучшения или комментарии?
- У вас есть лучшее / более простое решение?
- Видите ли вы проблемы в моем решении?
- Улучшения для правил .htaccess / rewrite
- Ссылки на реальные реализации API RESTful с Slim
- ....
Я с нетерпением жду ваших ответов, и мне было бы любопытно узнать, что нового.
Каждая новая версия должна быть новым проектом, который имеет собственный независимый кодбаза.Диспетчеризация версий должна выполняться сервером Apache, а не в коде PHP / Slim.Я нашел пример, который реализует различные версии API в проекте с помощью метода group.Но я не очень доволен этим решением.Мне удобнее иметь независимые проекты для независимых версий.
Я создаю структуру папок / файлов в папке htdocs следующим образом:
rest
+--api
+-v1
+-.htaccess
+-api.php
+-v2
+-.htaccess
+-api.php
+-.htaccess
Реализация API находится в файле api.php
.Сопоставление вызовов, подобных /rest/api/v1/books
, с моей реализацией. Я создаю в каждой папке версии файл .htaccess
, в котором содержатся правила для модуля переписывания Apache:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^$ / [QSA,L]
RewriteRule ^.*$ api.php [QSA,L]
Первое правило перезаписи должно соответствовать вызову /rest/api/v1
а второе правило переписывает пути типа /rest/api/v1/books
к реализации.
В api.php
я создаю несколько маршрутов
$app->get('/books', function ...
$app->get('/books/{id}', function ...
Все работает нормально, если я использую явную версию в URI(<host>/rest/api/v2/books
).Для удобства я создаю псевдоним latest (/rest/api/latest/books
), который перенаправляет вызов псевдонима на последнюю версию версии API.
Поэтому я создаю файл rest/api/.htaccess
, который переписывает URI для реализации:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^latest.*$ ./v2/api.php [QSA,L]
Правило перезаписи работает нормально и вызывается реализация v2.Но маршруты больше не совпадают.Я обнаружил, что исходный путь теперь является частью пути.
/rest/api/v2/books -> /books
/rest/api/latest/books -> /rest/api/latest/books
Если я изменил правила, как это, это работает - но я не люблю реализовывать каждое правило дважды.
$app->get('/rest/api/latest/books', function ...
$app->get('/rest/api/latest/books/{id}', function ...
Поэтому я написал функцию промежуточного программного обеспечения, которая обрезает /rest/api/latest
от пути до сопоставления маршрутов.
$app->add(function (Request $request, Response $response, callable $next) {
$uri = $request->getUri();
$path = $uri->getPath();
if (substr($path,0,16) == "/rest/api/latest") {
$uri = $uri->withPath(substr($path,16));
return $next($request->withUri($uri), $response);
}
return $next($request, $response);
});
Теперь я могу использовать одни и те же правила для обоих случаев, явного вызова версии и неявноговерсия вызова.