l5如何通过路由走api版本回退查找设置

l5如何通过路由走api版本回退查找设置

具体需求

当前遇到的问题是使用laravel写接口,但是接口是有版本号的,我们把版本号放在url中,比如:

http://yejianfeng.com/api/user/info/?uid=1
http://yejianfeng.com/api1.1/user/info/?uid=1
http://yejianfeng.com/api1.2/user/info/?uid=1

但是实际上api1.1的user/info和api的user/info的action是一样的,但是api1.2的user/info是不一样的

本来路由应该这么写:

<?php
Route::group(array('prefix' => 'api'), function() {
    Route::get('/user/info', ['uses' => 'UserController@userinfo']);
});

Route::group(array('prefix' => 'api1.1'), function() {
    Route::get('/user/info', ['uses' => 'UserController@userinfo']);
});

Route::group(array('prefix' => 'api1.2'), function() {
    Route::get('/user/info', ['uses' => 'UserController@userinfo1_2']);
});

这个感觉还是丑了点,我不希望路由会这么复杂,我希望的是进行版本衰退寻找,api1.1中的user/info那个不需要写,它能自动去寻找api1.1中有没有这个路由,没有的话,去寻找比它版本低的路由。

解决方法

这里当然要使用到middleware,希望路由是:

<?php
Route::group(array('prefix' => 'api'), function() {
    Route::get('/user/info', ['uses' => 'UserController@userinfo']);
});

Route::group(array('prefix' => 'api1.1', 'middleware' => 'downgrade'), function() {
});

Route::group(array('prefix' => 'api1.2', 'middleware' => 'downgrade'), function() {
    Route::get('/user/info', ['uses' => 'UserController@userinfo1_2']);
});

但是非常可惜,这样写的话

http://yejianfeng.com/api1.1/user/info/?uid=1

是进不了middleware的。

我们需要的是有个“匹配所有”的路由能将路由定位定到prefix 1.1的这个里面

所以改成这样:

<?php
Route::group(array('prefix' => 'api'), function() {
    Route::get('/user/info', ['uses' => 'UserController@userinfo']);
});

Route::group(array('prefix' => 'api1.1', 'middleware' => 'downgrade'), function() {
    Route::any('/{c}/{a}', function(){});
});

Route::group(array('prefix' => 'api1.2', 'middleware' => 'downgrade'), function() {

    Route::get('/user/info', ['uses' => 'UserController@userinfo1_2']);

    Route::any('/{c}/{a}', function(){});
});

这里就能将所有的/{version}/{controller}/{action}这样的请求经过downgrade中间件了。

但是中间件怎么写呢?

downgrade中间件的编写

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Routing\Middleware;

class DownGradeMiddleware implements Middleware {

    public function handle($request, Closure $next)
    {
        $routeAction = $request->route()->getAction();
        $routes = \Route::getRoutes()->getRoutes();

        $requestUri = $_SERVER['REQUEST_URI'];
        $querys = explode('?', $requestUri);
        $queryPath = trim($querys[0], '/');
        $querySecs = explode('/', $queryPath);

        // 没有对应的,进行api版本回找
        $versions = ['api', 'api1.1', 'api1.2'];

        $apiversion = $querySecs[0];
        $key = array_search($apiversion, $versions);
        while (1) {
            if ($key < 0) {
                break;
            }
            $querySecs[0] = $versions[$key];
            $queryPath = trim(implode('/', $querySecs), '/');

            foreach ($routes as $route) {
                if ($route->getUri() == $queryPath) {
                    $action = $route->getAction();
                    $routeAction['uses'] = $action['uses'];
                    $request->route()->setAction($routeAction);
                    return $next($request);
                }
            }

            $key--;
        }

        $response = $next($request);

        return $response;
    }
}

这里最重要的点就是将$routeAction的uses字段修改之后,调用

$request->route()->setAction($routeAction);

就可以修改路由对应的action了

其他的就是业务逻辑的问题了。

至于如何挂载middleware,可以参考laravel文档:路由进行挂载

总结

laravel4把匹配全路由的函数去掉了,但是其实使用中间件+any("{a}/{b}/{c}") 的方法也可以近似实现一个这样的功能的。

so,总是有路通向罗马的。

时间: 2024-11-01 11:13:47

l5如何通过路由走api版本回退查找设置的相关文章

Git的纯命令操作,Install,Clone , Commit,Push,Pull,版本回退,撤销更新,分支的创建/切换/更新/提交/合并,代码冲突

Git的纯命令操作,Install,Clone , Commit,Push,Pull,版本回退,撤销更新,分支的创建/切换/更新/提交/合并,代码冲突 这篇是接着上篇分布式版本库--Windows下Git的环境部署以及在GitHub上开源自己的项目讲的,上篇主要是说用GUI来图形化界面操作,但是一般我们程序员也不会这么干,用命令又轻松又愉悦,所以,这里我就再开了一篇来专门说一下纯命令是怎么去操作的,但是要注意哦,其实廖雪峰老师的网站就是非常赞的学习资源哦! 廖雪峰老师:http://www.li

怎么添加android studio虚拟机的API版本?

问题描述 怎么添加android studio虚拟机的API版本? 我在创建虚拟机时里面只有API 22的版本,没有低版本.在选择API界面一直卡死,没有其他选择,请问有其他方法能添加API版本吗? 解决方案 需要在SDK Manager里面下载相应版本的SDK, 才能在你上面截图里面出现

远程仓库版本回退方法 good

1 简介 最近在使用git时遇到了远程分支需要版本回滚的情况,于是做了一下研究,写下这篇博客. 2 问题 如果提交了一个错误的版本,怎么回退版本? 如果提交了一个错误的版本到远程分支,怎么回退远程分支版本? 如果提交了一个错误的版本到公共远程分支,又该怎么回退版本? 3 本地分支版本回退的方法 如果你在本地做了错误提交,那么回退版本的方法很简单 先用下面命令找到要回退的版本的commit id: git reflog 接着回退版本: git reset --hard Obfafd 0bfafd就

Git 系列(四):在 Git 中进行版本回退

在这篇文章中,你将学到如何查看项目中的历史版本,如何进行版本回退,以及如何创建 Git 分支以便你可以大胆尝试而不会出现问题. 在你的 Git 项目的历史中,你的位置就像是摇滚专辑中的一个片段,由一个被称为 HEAD 的 标记来确定(如磁带录音机或录音播放器的播放头).要在你的 Git 时间线上前后移动 HEAD ,需要使用 git checkout 命令. git checkout 命令的使用方式有两种.最常见的用途是从一个以前的提交中恢复文件,你也可以整个倒回磁带,切换到另一个分支. 恢复一

我要获取anroid系统,&amp;amp;quot;是否开启了默认锁屏&amp;amp;quot;,在android api中未查找到参数,如下图.

问题描述 我要获取anroid系统,"是否开启了默认锁屏",在android api中未查找到参数,如下图. 我开始想通过"Settings.System.getInt"来获取参数,但读了anroid api下Settings.System的参数,没找着合适的,各位大神,有没有好办法 解决方案 http://www.2cto.com/kf/201404/296615.html

淘宝不支持低版本浏览器,设置了UserAgent也还是提示,奇怪了。

问题描述 淘宝不支持低版本浏览器,设置了UserAgent也还是提示,奇怪了. HttpWebRequest sendreq1sessionidpost = WebRequest.Create("https://login.taobao.com/member/login.jhtml") as HttpWebRequest; sendreq1sessionidpost.Method = "post"; sendreq1sessionidpost.CookieConta

ext5.0 api文档查找疑问this.getView().down() , down()找不到

问题描述 ext5.0 api文档查找疑问this.getView().down() , down()找不到 Ext.define('app.view.module.ModuleController', { extend : 'Ext.app.ViewController', alias : 'controller.module', deleteRecords : function(button) { var grid = this.getView().down('modulegrid'); /

idea中git远程版本回退

工作中遇到git远程仓库需要回退到历史版本的问题,根据网上的搜索结果结合自己的实践,整理了如下步骤: 1. 在"Show History"中找到当前版本(取名:newVersion)和想要回退到的版本(oldVersion) 2. 选择newVersion和oldVersion点击"Copy Revision Number"复制两个版本的版本号: newVersion:2746f428a3d3d000bd1b0e886ef8167e1f73ec9c oldVersi

Android Studio git 版本回退到最新的版本

1.场景      1.1 最新三次的提交          分别是:定义了一个变量k = 10 . 定义了一个变量 j = 6  . 定义了一个变量 i = 5 ;          本地仓库 和 远程仓库保持一致            1.2  我添加了一行代码                      如何回退版本到最近的一次,也就是 定义一个变量 k = 10 这个版本 ?                                 回退的结果