为我的php应用程序(社交应用程序)创建API版本控制

时间:2019-05-28 21:08:01

标签: php api versioning

我目前正在开发社交应用程序。

我想在我的PHP后端上安装一个版本控制系统,但是我不知道从哪里开始:我在网上查找了很多文章,但是我真的不明白我所发现的内容。

比方说我的应用程序是v1.0。然后,我创建了一个新版本v2.0,当然我也更新了PHP文件。此后,如果某人尚未从v1.0更新其应用程序,那么我希望他们达到myapp.com/v1.0/,以便该应用程序不会崩溃。

您会推荐什么?

我的典型PHP文件如下所示:

<?php

// Include files

include_once ('../../config.php');

include_once (ROOT_DIR . '/config/includes.php');

$_USERDATA = Validator::validateUser($_POST["userId"], $_POST["session"]);

// Valid session

$qry = $db->prepare('SELECT n.id, n.type, n.time, n.isRead, n.postId, n.commentId, n.text, n.inReplyToCommentId, u.id as byUserId, 
    ( SELECT COUNT(nu.id)
    FROM notificationUsers AS nu
    WHERE nu.notificationId = n.id ) as detail1,
    ( SELECT nu2.userId
    FROM notificationUsers AS nu2
    WHERE nu2.notificationId = n.id ORDER BY nu2.id DESC LIMIT 1 ) as latestUserId FROM notifications AS n LEFT JOIN userData AS u ON n.byUserId = u.id
    WHERE n.userId = :userId ORDER BY n.time DESC');
$qry->bindParam(':userId', $_USERDATA["userId"], PDO::PARAM_INT);
$qry->execute();

$notificationsArray = $qry->fetchAll(PDO::FETCH_ASSOC);


$returnValue = array();
$returnValue["status"] = "1";
$returnValue["title"] = "Success";
$returnValue["message"] = "Downloaded notifications";
$returnValue["data_notifications"] = $notificationsArray;
exit(json_encode($returnValue));



?>

...

更新1

所以我决定执行以下操作:

将每个未共享的文件放入文件夹中,如下所示:

/api/v1.0/file.php

但是每个资源(例如图片)都在api之外

/resources/images/profilepictures/image.jpg

如果我做了微小的更改,我只是更新api/v1.0/文件夹中的文件。

然后,所有使用Application v1.1的用户都在请求myapp.com/api/v1.1/,但是我将他们重定向到api / v1.0 /,在这里我可以向用户显示正确的数据(取决于是否该请求来自v1.0或v1.1)

如果这些版本加起来并且发布了更大的更新,我将创建一个名称为v2.0的新文件夹,这样就可以了...

或者您怎么看。我该怎么办?

3 个答案:

答案 0 :(得分:2)

您正在定义体系结构,以便将来验证设计,这是很好的第一步。

如果您使用Laravel或Symfony之类的框架,则可以使Models和Helpers目录保持公用,同时将Controllers目录版本化为诸如v1.x,v2.x等子目录。

如果使用路由机制,这可以使您的生活变得轻松,例如,假设您的v1.0具有50个API端点,并且您打算修改其中的5个以实现v1.2,而没有向后兼容性,在这种情况下,其余所有45个API端点仍将与v1.0相同,并且您不想在v1.2目录中重复它们。

<?php

$versions = ["v1.0", "v1.2"];

route("/api/v1.0/foobar", "Controllers/v1.0/FoobarController@doSomething");
route("/api/v1.0/footar", "Controllers/v1.0/FoobarController@doTar");

route("/api/v1.2/foobar", "Controllers/v1.2/FoobarController@doSomething");

function route($endpoint, $controller)
{
    // Logic to call function of a respective class/file 
    // and call previous version of an API if function/endpoint is not redefined in current version
}
?>

因此,在上述情况下,当客户端调用/api/v1.2/footar时,应该为API使用者执行/api/v1.0/footar。

希望对您有帮助。

答案 1 :(得分:1)

许多其他答案建议使用框架(Symfony等),它们具有优点(更多的即插即用)和缺点(它们有很多样板可实现)。设定)。我将针对该问题的纯本机PHP解决方案进行重点研究,

1。保持代码库尽可能小(很少重复)  
2。支持最简单的实现(由于减少了样板,因此比框架解决方案更具优势)

这将是该解决方案的示例实现。 index.php(第一个文件):

<?php
require_once("path/to/config");
require_once("path/to/helpers/that/are/used/by/both/apis");

//This is where we decide where to route the request
if(strpos('/v1/', $_SERVER["REQUEST_URI"]) {
    //This is api v1 so use api v1
    require_once("path/to/api/objects/1.0");
} else {
    //This is api v2 (or the default since most recent)
    require_once("path/to/api/objects/2.0");
}
//Use the classes just imported to handle the request:
$apiObject = new Responder(); //Imported from one of the two api versions
echo $apiObject->handle(); 

?>

上面的代码基于解析URL来区分两个API,并为每个API导入一个不同的类。

对于每种类型的导入的API文件,它们都可以扩展相同的父API类(减少总代码),具有完全相同的方法名称,并且部分或全部方法的行为不同。

对于真正简单甚至更复杂的后端PHP服务,这是一种更为优雅的解决方案。

答案 2 :(得分:0)

正如我所看到的,您希望使用不带任何框架的纯PHP编写API。 我只是想引导您采用正确的方法,并给您一些愿景,以用PHP启动服务器端开发。

  • 首先选择一个框架进行编码。也许CodeIgniter,它是一个易于使用的[阅读以下内容]
  • 有关 MVC 设计模式的研究,大多数框架都支持该模式,当您想要维护或扩展现有代码时,这将使您的生活变得轻松-这是必要且容易的,不要害怕
  • 克隆整个项目以实现向后兼容性是一个过大的选择(假定您只想修复数据库访问层(模型/存储库)中的错误,应对所有其他版本重复此操作)-您可以通过仅克隆Controller来实现和定义新路线-[由于设计模式,您仍然在Controller层的业务逻辑中遇到了先前的问题]
  • 如果您想采用更强大的方法,则应从具有服务层(又称为MVCS)的存储库模式开始编码,并使用所需的框架(可能是Laravel)来防止不同版本的控制器层之间的代码耦合,并保持在服务层中共享业务逻辑(与控制器分开)
  • 通过使用文档注释标签(例如@deprecated和@since)来指定代码中的重要内容,以指定何时不推荐使用或添加某些功能(因为在相关版本退役之前,您无法清除不推荐使用的功能。) this link得到想法]
  • 有关版本标准的研究-SEMVER
  • 请勿使用纯PHP编写代码