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版本回退查找设置的更多相关文章

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

    Git的纯命令操作,Install,Clone , Commit,Push,Pull,版本回退,撤销更新,分支的创建/切换/更新/提交/合并,代码冲突 这篇是接着上篇分布式版本库--Windows下G ...

  2. git 版本回退

    由于操作失误,需要将代码进行版本回退,首先在本地仓库执行了“git reset --hard HEAD^”命令,这样只会回退本地仓库的代码,但是我的代码之前已经push到了远程库中,查看远程仓库,发现 ...

  3. git误删文件找回方法/git版本回退方法

    使用git命令 git rm css/\*.css 我删掉了css文件夹下所有以.css结尾的文件,那么要怎样才能把文件找回来呢,下面说说方法,删掉其他的文件也是一样的方式找回. 第一步:使用git ...

  4. git版本回退, github版本回退

    上周提交了更改,过了周末回来说要撤销上个story.于是,需要找到上周提交的版本,rollback回来. git版本管理命令,自从习惯使用管理工具之后就很少接触了,当突然寻找其他指令的时候就成浆糊了, ...

  5. 【Git学习笔记】初始化Git仓库和版本回退

    学习地址 http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 什么是版本库呢?版本库又 ...

  6. git中的版本回退

    git版本回退有两种情况,一种是从本地版本库中(head区)回退到某个版本,可以用命令 git reset --hard head^ 或git reset --hard head~x ,head指的是 ...

  7. Git秘籍:在 Git 中进行版本回退

    导读 在这篇文章中,你将学到如何查看项目中的历史版本,如何进行版本回退,以及如何创建 Git 分支以便你可以大胆尝试而不会出现问题.快来试试吧. 在你的 Git 项目的历史中,你的位置就像是摇滚专辑中 ...

  8. SVN版本回退

    [SVN版本回退] 在Windows里,先打开Log面板,根据想要回退的内容,然后选择revert to this revision或者revert changes from this revisio ...

  9. git分支与版本管理、版本回退、冲突解决记录

    一.基础使用 1.初始化本地仓库 git init 2.关联远程仓库 git remote add origin git@github.com:用户名/仓库名.git 3.添加远程仓库文件到本地 gi ...

随机推荐

  1. mac下android环境搭建笔记(android studio)

    本文记录了本人在mac上配置android开发环境的一些过程,为了方便直接选用了官方的IDE– Android Studio .本文包括了android studio的安装.创建第一个hello wo ...

  2. 我的ORM之三 -- 更新

    我的ORM索引 更新语法 var 影响行数 = dbr.表.Update(实体).Where(条件).Execute(); 实体类型: 更新的实体类型和添加的实体类型一样,有三类: 1. 任何C#类. ...

  3. 讲讲HashCode的作用

    前言 Object提供给我们了一个Native的方法“public native int hashCode();”,本文讲讲Hash是什么以及HashCode的作用 Hash 先用一张图看下什么是Ha ...

  4. 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码【123和12345】那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出的电话号码(java实现)

    解题: 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码[123和12345]那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出 ...

  5. [PCB设计] 1、硬件原理图设计规范(一)——基本原则

    1.1 目的 原理图设计是产品设计的理论基础,设计一份规范的原理图对设计PCB.跟机.做客户资料具有指导性意义,是做好一款产品的基础.原理图设计基本要求: 规范.清晰.准确.易读. 因此制定此< ...

  6. Win + D 和 Win + M的区别

    在Windows系统上,Win + D是显示桌面,Win + M是最小化所有窗口,咋一看,这两个快捷键貌似没有区别,但是在某些方面还是有细微的区别. 威力 从威力上来说,Win + D更牛逼一,因为显 ...

  7. 12小时包你学会基于ReactMix框架的ReactNativeApp开发(一)Hello World!

    ReactMixhttps://github.com/xueduany/react-mix自从昨天发布起来,得到了不少小伙伴的热捧,很高兴帮助大家解决了憋在心中很久的问题“如果我只会HTML,Css, ...

  8. linux网络编程系列-网络连接的建立

    一个比较实用的连接函数,支持host为域名. #include <netdb.h> #include <sys/socket.h> #include <sys/types ...

  9. Atitit 热更新资源管理器 自动更新管理器 功能设计

    Atitit 热更新资源管理器 自动更新管理器 功能设计 · 多线程并行下载支持 · 两层进度统计信息:文件级以及字节级 · Zip压缩文件支持 · 断点续传 · 详细的错误报告 · 文件下载失败重试 ...

  10. 浅谈iOS版本号

    作者:Travis FIR.im 一直在尽量兼容不同使用习惯的版本号形式, 但是在使用中我们发现好多开发者对怎么更好的用版本号来标示应用很陌生. 这是篇基础文章, 简单介绍 iOS 的版本号. 名词解 ...