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,总是有路通向罗马的。
l5如何通过路由走api版本回退查找设置的更多相关文章
- Git的纯命令操作,Install,Clone , Commit,Push,Pull,版本回退,撤销更新,分支的创建/切换/更新/提交/合并,代码冲突
Git的纯命令操作,Install,Clone , Commit,Push,Pull,版本回退,撤销更新,分支的创建/切换/更新/提交/合并,代码冲突 这篇是接着上篇分布式版本库--Windows下G ...
- git 版本回退
由于操作失误,需要将代码进行版本回退,首先在本地仓库执行了“git reset --hard HEAD^”命令,这样只会回退本地仓库的代码,但是我的代码之前已经push到了远程库中,查看远程仓库,发现 ...
- git误删文件找回方法/git版本回退方法
使用git命令 git rm css/\*.css 我删掉了css文件夹下所有以.css结尾的文件,那么要怎样才能把文件找回来呢,下面说说方法,删掉其他的文件也是一样的方式找回. 第一步:使用git ...
- git版本回退, github版本回退
上周提交了更改,过了周末回来说要撤销上个story.于是,需要找到上周提交的版本,rollback回来. git版本管理命令,自从习惯使用管理工具之后就很少接触了,当突然寻找其他指令的时候就成浆糊了, ...
- 【Git学习笔记】初始化Git仓库和版本回退
学习地址 http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 什么是版本库呢?版本库又 ...
- git中的版本回退
git版本回退有两种情况,一种是从本地版本库中(head区)回退到某个版本,可以用命令 git reset --hard head^ 或git reset --hard head~x ,head指的是 ...
- Git秘籍:在 Git 中进行版本回退
导读 在这篇文章中,你将学到如何查看项目中的历史版本,如何进行版本回退,以及如何创建 Git 分支以便你可以大胆尝试而不会出现问题.快来试试吧. 在你的 Git 项目的历史中,你的位置就像是摇滚专辑中 ...
- SVN版本回退
[SVN版本回退] 在Windows里,先打开Log面板,根据想要回退的内容,然后选择revert to this revision或者revert changes from this revisio ...
- git分支与版本管理、版本回退、冲突解决记录
一.基础使用 1.初始化本地仓库 git init 2.关联远程仓库 git remote add origin git@github.com:用户名/仓库名.git 3.添加远程仓库文件到本地 gi ...
随机推荐
- GitHub详解(GitHub for Windows)
GitHub详解 GitHub 是一个共享虚拟主机服务,用于存放使用Git版本控制的软件代码和内容项目.它由GitHub公司(曾称Logical Awesome)的开发者Chris Wanstrath ...
- javascript 设计模式-----模块模式
在一些大的项目中经常使用到模块,在这里,我们将了解一下什么是模块模式.模块模式最简单的方法大家一定会用过,如下所示: var a = { b : 1, c : 2 } 这样一个对象的直接量其实就已经是 ...
- Windows Phone 8.1上的开发人员请看
1)SDK选择:如果你是在Windows Phone 8.1上做一个新App, 或者想把7.x/8.0的App移植到8.1上,请使用WinRT SDK,而不是Silverlight.当然Silverl ...
- 开发者必知的几款App快速开发工具
“我有一个好创意,就差一个CTO……” ,这是今年炒的比较火的一句话. “原生APP开发难度大,周期长,成本高,还没上线市场已经被占领了.这个有没有解决方案?” “APP版本迭代更新,都是企业的一道难 ...
- ASP.NET MVC 随想录—— 使用ASP.NET Identity实现基于声明的授权,高级篇
在这篇文章中,我将继续ASP.NET Identity 之旅,这也是ASP.NET Identity 三部曲的最后一篇.在本文中,将为大家介绍ASP.NET Identity 的高级功能,它支持声明式 ...
- CSS media queries
最近在做一些页面打印时的特殊处理接触到了media queries,想系统学习一下,在MOZILLA DEVELOPER NETWORK看到一篇文章讲的很不错,结合自己的使用总结一下. CSS2/me ...
- C#入门基础三
封装:简化用户接口,隐藏实现细节. get{return 属性值:} set{属性值 = value:} 继承:子类继承父类所有非私有成员.继承具有传递性,单根性. 隐式继承:用引号(:)实现. 显示 ...
- cmd 下通过NTML代理访问Maven 库
公司用web代理,NTLM验证的,这样在普通CMD下无法使用mvn命令访问网上的maven库,使用CNTLM工具解决. 下载CNTLM工具,安装,修改安装路径下的cntlm.ini,改成实际的ntlm ...
- thinkphp里的session、cookie方法
thinkphp里,对于session和cookie的操作,不管是存值.获取.删除,均只有一个方法.现分享出来,供大家参考参考. /** * session管理函数 * @param string|a ...
- PDO连接mysql和pgsql数据库
PDO连接mysql数据库 <?php $dsn="mysql:host=localhsot;dbname=lamp87"; $user="root"; ...