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 ...
随机推荐
- hadoop+hive使用中遇到的问题汇总
问题排查方式 一般的错误,查看错误输出,按照关键字google 异常错误(如namenode.datanode莫名其妙挂了):查看hadoop($HADOOP_HOME/logs)或hive日志 h ...
- JavaScript开发原生App模式能否突出重围?
移动应用制作的第三方服务市场已经被瓜分得差不多了,对于刚起步的中小企业来说,这些公司的 IT 部门人员比较熟悉的是 Appcan ,但随着互联网公司对 App 开发的需求持续升温,也有不少后来的闯入者 ...
- 【读书笔记】Ninject 在MVC5中的使用
从MVC3中就开始接触Ninject这个IOC工具.也一直是MVC Framework系列书籍中推荐的IOC工具,当然还有优秀的Autofac等.性能和使用上面个有千秋.下面先看一下Ninject的使 ...
- prerender-SPA程序的SEO优化策略
随着web2.0的兴起,ajax的时代已经成为了事实,更如今Knockout,backbone, angular,ember前端MDV(model driver view)框架强势而来,Single ...
- 用python实现的百度新歌榜、热歌榜下载器
首先声明,本工具仅仅为学习之用,不涉及版权问题,因为百度音乐里面的歌曲本身是可以下载的,而且现在百度也提供了”百度音乐播放器”,可以通过这个工具进行批量下载. 我当时做这个工具的时候,百度还没有提供” ...
- 初识jsonp
jsonp 全称是JSON with Padding,是为了解决跨域请求资源而产生的解决方案.很多时候我们需要在客户端获取服务器数据进行操作,一般我们会使用ajax+webservice做此事,但是如 ...
- 谨慎DateTime.Now在EF的query中的使用
执行如下代码: var query = from tr in _carrierRepository select new BaseCarrier { CarrierCode = tr.CarrierC ...
- css 常见时间轴的做法(————————————————时间轴——————————————————)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- EF架构~基于EF数据层的实现
回到目录 之前写过关于实现一个完整的EF架构的文章,文章的阅读量也是满大的,自己很欣慰,但是,那篇文章是我2011年写的,所以,技术有些不成熟,所以今天把我的2014年写的EF底层架构公开一下,这个架 ...
- Atitit 编程语言原理与概论attilax总结 三大书籍总结
Atitit 编程语言原理与概论attilax总结 三大书籍总结 编程语言原理(第10版) 目录: 第1章 预备知识第2章 主要程序设计语言的发展第3章 描述语法和语义第4章 词法分析和语法分析第5章 ...