遵循基于条件的REST路由

时间:2014-07-17 10:48:48

标签: php rest routing

背景:我正在开发一种需要客户端 - 服务器通信的回合制游戏。客户端通过HTTPS使用RESTful请求,服务器使用JSON响应。我不使用REST,因为我需要公开API,但因为REST范例很容易解决客户端/服务器交互。服务器用PHP编写。

为了帮助我完成路由REST请求,我一直在寻找一个有用的路由库。它们数量惊人,但我很难找到符合我特定需求的产品。我的问题是:如果满足某些条件,只允许玩家遵循某些路线。显然,我可以检查路由匹配后调用的方法是否满足条件,但这似乎是一种容易出错的方法,因为许多路由的条件相同。首先进行部分匹配会更简单,然后决定必须满足一些条件才能在部分匹配下遵循更具体的路线。

为了说明,游戏中有4个级别的“身份验证”:

  1. 未经过身份验证
  2. 经过身份验证{id}(我们知道它是哪个播放器)
  3. 经过身份验证{id}和参与者{sesid}
  4. 认证为{id},参加会话{sesid},并且轮到玩家了
  5. 现在假设身份验证在后台进行。您可以逐步在每个级别上遵循的路线:

    第1级:

    • POST \ Players-注册

    第2级:

    • PUT \ Players \ {id} - 更改个人资料
    • GET \ Players \ {id} \ Sessions - 获取会话列表
    • POST \ Players \ {id} \ Sessions - 创建会话
    • POST \ Players \ {id} \ Inventory - 购买物品
    • PUT \ Players \ {id} \ Invites \ {sesid} - 加入会话邀请
    • DELETE \ Players \ {id} \ Invites \ {sesid} - 拒绝会话邀请

    第3级:

    • GET \ Players \ {id} \ Sessions \ {sesid} - 获取会话状态
    • DELETE \ Players {id} \ Sessions \ {sesid} - 取消会话

    第4级:

    • PUT \ Players \ {id} \ Sessions \ {sesid} \ ... - 设置多个会话状态参数

    所以我希望在匹配下一组路线之前先检查一些参数。我花了很多时间在Google和Packagist上寻找合适的路由包(我看过Klein,Zend,PHP-Router,Fat_free,Slim,TORO,Aura,FlightPHP,Phalcon,FuelPHP的文档,仅举几例)但几乎所有的图书馆都要求您预先定义路线并一次性找到一个匹配 - 有时允许您设置订单,有时从最具体到最不具体,但大多只执行一条路线。

    如果我能按照定义的顺序进行部分路线匹配,我会有所帮助 - 例如,任何以玩家\ {id}开头的路线首先检查身份验证,当不存在时退出,同时继续检查下一个模式如果认证正常,则按定义的顺序。

    允许我在现场匹配和执行路由的任何路由库也会有所帮助 - 只要它可以进行部分匹配,这样我就可以选择我需要的参数来检查身份验证级别要求(id,sesid) 。显然,为了保持苗条,我更喜欢一个不属于更大框架的库。

    在我在Packagist上阅读的文档页面中,我很难发现你是否可以部分匹配某些库中的路由 - 匹配参数,是,但路由? - 有时候不清楚发现的第一场比赛是否是唯一的比赛。有什么指针吗?

    或者我在这里错过了一个更简单的解决方案?

1 个答案:

答案 0 :(得分:1)

嗯,首先,Klein将允许您为同一个回调执行多个路由,如下所示:

// This route matches everything
$klein->respond('*', function ($request, $response, $service) { myAuthFunction($request); });
//other routes
// This route matches only a specific path
$klein->respond('GET', '/Players/[i:id]/Sessions', function ($request, $response, $service) { echo "This is the Sessions page for User ID $request->id"; })

查看routing上的部分,然后滚动到以“注意”开头的段落。如果我没记错的话,路由按照它们被声明的顺序执行,所以你抓住你用来检查凭据的所有路由都需要先在更具体的路由之前。

在您的auth函数中,您需要抛出异常,以防止后续路由被运行,然后捕获它。 This link显示了如何捕获抛出HTTP错误。要抛出一个,只需在回调中调用$router->abort(404)即可。你必须使用use发送$ router(你的Klein实例),所以你的回调实际上是:

$klein->respond('*', function ($request, $response, $service) use ($klein) { myAuthFunction($request); });

还有一个路由namespace系统,我看过它,但没有使用过自己,但可能对你要做的事情有所帮助。

最后,我最终做的是将我的操作分组到控制器中,并在控制器的构造函数中进行权限检查。如果你不认为它与你相关,我不想浪费很多时间来解释如何设置它,但我可以根据要求提供更多细节。

最后一点,文档说要像这样安装Klein:

php composer.phar require klein/klein v2.0.x

但我发现dev-master代码效果更好,所以我建议这样做:

php composer.phar require klein/klein dev-master

希望有所帮助!