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
AI 代码解读

但是实际上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']);
});
AI 代码解读

这个感觉还是丑了点,我不希望路由会这么复杂,我希望的是进行版本衰退寻找,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']);
});
AI 代码解读

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

http://yejianfeng.com/api1.1/user/info/?uid=1
AI 代码解读

是进不了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(){});
});
AI 代码解读

这里就能将所有的/{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;
    }
}
AI 代码解读

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

$request->route()->setAction($routeAction);
AI 代码解读

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

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

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

总结

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

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




本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/p/4413749.html,如需转载请自行联系原作者

目录
打赏
0
0
0
0
56
分享
相关文章
如何在Java爬虫中设置动态延迟以避免API限制
如何在Java爬虫中设置动态延迟以避免API限制
微服务架构下RESTful风格api实践中,我为何抛弃了路由参数 - 用简单设计来提速
本文探讨了 RESTful API 设计中的两种路径方案:动态路径和固定路径。动态路径通过路径参数实现资源的 CRUD 操作,而固定路径则通过查询参数和不同的 HTTP 方法实现相同功能。固定路径设计提高了安全性、路由匹配速度和 API 的可维护性,但也可能增加 URL 长度并降低表达灵活性。通过对比测试,固定路径在性能上表现更优,适合微服务架构下的 API 设计。
115 1
ThinkPHP 资源路由的简单使用,restfull风格API
本文介绍了在ThinkPHP框架中使用资源路由来创建RESTful风格的API,包括如何通过命令行创建资源控制器,注册资源路由,以及资源控制器中各方法的默认操作和测试方法。
ThinkPHP 资源路由的简单使用,restfull风格API
视觉智能开放平台产品使用合集之海外是否可以访问人物动漫化的api版本
视觉智能开放平台是指提供一系列基于视觉识别技术的API和服务的平台,这些服务通常包括图像识别、人脸识别、物体检测、文字识别、场景理解等。企业或开发者可以通过调用这些API,快速将视觉智能功能集成到自己的应用或服务中,而无需从零开始研发相关算法和技术。以下是一些常见的视觉智能开放平台产品及其应用场景的概览。
102 0
【Azure 环境】调用Azure RunCommand 的REST API 设置虚拟机的环境变量(SetEnvironmentVariable)
【Azure 环境】调用Azure RunCommand 的REST API 设置虚拟机的环境变量(SetEnvironmentVariable)
【Azure API 管理】通过Java APIM SDK创建一个新的API,如何为Reqeust的Representation设置一个内容示例(Sample)?
【Azure API 管理】通过Java APIM SDK创建一个新的API,如何为Reqeust的Representation设置一个内容示例(Sample)?
【Azure API 管理】API Management如何有效且快速更新呢?如对APIs/Policy等设置内容
【Azure API 管理】API Management如何有效且快速更新呢?如对APIs/Policy等设置内容
|
9月前
|
API
【Azure API 管理】Azure API Management在设置 Policy时,如何对URL进行解码呢? 使用 HttpUtility.UrlDecode 出错
【Azure API 管理】Azure API Management在设置 Policy时,如何对URL进行解码呢? 使用 HttpUtility.UrlDecode 出错
【Azure API 管理】APIM集成内网虚拟网络后,启用自定义路由管理外出流量经过防火墙(Firewall),遇见APIs加载不出来问题
【Azure API 管理】APIM集成内网虚拟网络后,启用自定义路由管理外出流量经过防火墙(Firewall),遇见APIs加载不出来问题
101 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等