首页 > 解决方案 > 使用 PHP/Slim 和 Apache 实现 RESTful API 的版本控制

问题描述

根据一些评论,我在CodeReview上创建了一个问题。


我想用 Apache/PHP 和 Slim Framework (3.x) 创建一个 RESTful API。API 应支持基于 URI 的版本控制,例如<host>/rest/api/v1/<resource><host>/rest/api/latest/<resource>.

总的来说,我找到了一个可行的解决方案,但我对我的解决方案并不满意,我想知道我可以做得更好。我是 Slim 的新手/新手。我正在寻找新的想法以及如何提高我对 Slim 的了解。

我期待着你的回答,我很想看看有什么新东西。


每个新版本都应该是一个新项目,有自己独立的代码库。版本调度应该由 Apache 服务器完成,而不是在 PHP/Slim 代码中。我发现了一些使用 group-method 在项目中实现不同版本的 API 的示例。但我对这个解决方案不是很满意。我觉得有独立版本的独立项目会更好。

我在 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);
});

现在我可以对两种情况使用相同的规则,显式版本调用和隐式版本调用。

标签: phpapacherest.htaccessslim

解决方案


推荐阅读