mehrdad-dadkhah/laravel-vroute 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

mehrdad-dadkhah/laravel-vroute

Composer 安装命令:

composer require mehrdad-dadkhah/laravel-vroute

包简介

PHP library for laravel to add automated/conventional routes with versioning

README 文档

README

Software License Packagist Version

PHP library for laravel to add automated/conventional routes with versioning.

This package help developers and teams to have versioning URI base on project structure, and no need to write new line of code for new route.

This package is configable for example you can change template of controller names and ....

If you have index method in version 1 of PostController and you call /api/v1/post so router call index method of version 1 immidately, but if call /api/v2/post what happen?

you have 3 choice:

  1. move all codes from version 1 to version 2!

  2. add new route for /api/v2/post that point to version 1!

  3. in your application you use different version of api base on active version of it! you have know multiple active api version, you should support all, you should remember or check every day! where which version is in use and .....

So to fix this problem/need I develop this package. VRoute for /api/v2/post check version 2 of PostController and if it has not this method automatically switch to one version.

Maybe you ask this process is heavy and may make performance problem, yes but I add good caching system to it and we process only one time.

Benefit case and samples

  1. Simplification and less code

    Before using VRoute you may have something like this:

    Route::namespace('Admin')->prefix('admin')->group(function () {
    
        Route::namespace('V1')->prefix('v1')->group(function () {
    
            Route::post('users/login', 'UserAPIController@login');
            Route::post('users/refresh-token', 'UserAPIController@refreshToken');
            Route::post('users/forget-password', 'UserAPIController@forgetPassword');
            Route::post('users/register', 'UserAPIController@register');
    
            Route::resource('faqs', 'FaqAPIController');
            Route::get('settings/check-version', 'SettingAPIController@checkVersion');
    
            Route::group(['middleware' => 'auth:api'], function () {
                Route::post('users/logout', 'UserAPIController@logout');
                Route::get('users/show', 'UserAPIController@show');
                Route::put('users/notification-toggle', 'UserAPIController@toggleStatusNotification');
    
                Route::get('users/channels', 'UserTaggingAPIController@channels');
    
                /** ---------------------- ACL middleware  ---------------------- */
                Route::middleware(['acl'])->group(function () {
                    Route::get('scores/totals', 'ScoreAPIController@totals');
                    Route::resource('posts', 'PostAPIController');
                });
            });
        });
    });
    
    Route::namespace('Client')->prefix('client')->group(function () {
    
        Route::namespace('V1')->prefix('v1')->group(function () {
    
            Route::post('users/login', 'UserAPIController@login');
            Route::post('users/refresh-token', 'UserAPIController@refreshToken');
            Route::post('users/forget-password', 'UserAPIController@forgetPassword');
            Route::post('users/register', 'UserAPIController@register');
    
            Route::resource('faqs', 'FaqAPIController');
            Route::get('settings/check-version', 'SettingAPIController@checkVersion');
    
            Route::group(['middleware' => 'auth:api'], function () {
                Route::post('users/logout', 'UserAPIController@logout');
                Route::get('users/show', 'UserAPIController@show');
                Route::put('users/notification-toggle', 'UserAPIController@toggleStatusNotification');
    
                Route::get('users/channels', 'UserTaggingAPIController@channels');
    
                /** ---------------------- ACL middleware  ---------------------- */
                Route::middleware(['acl'])->group(function () {
                    Route::get('scores/totals', 'ScoreAPIController@totals');
                    Route::resource('posts', 'PostAPIController');
                });
            });
        });
    
        Route::namespace('V2')->prefix('v2')->group(function () {
    
            Route::post('users/login', 'UserAPIController@login');
            Route::post('users/refresh-token', 'UserAPIController@refreshToken');
            Route::post('users/forget-password', 'UserAPIController@forgetPassword');
            Route::post('users/register', 'UserAPIController@register');
    
            Route::resource('faqs', 'FaqAPIController');
            Route::get('settings/check-version', 'SettingAPIController@checkVersion');
    
            Route::group(['middleware' => 'auth:api'], function () {
    
                Route::get('users/channels', 'UserTaggingAPIController@channels');
    
                /** ---------------------- ACL middleware  ---------------------- */
                Route::middleware(['acl'])->group(function () {
                    Route::resource('posts', 'PostAPIController');
                });
            });
        });
    
    });

    And after use VRoute it would be:

    VRoute::setAvailableSubDirs([
        'admin',
        'client',
    ]);
    
    VRoute::setMiddleware('UserAPIController', 'POSTLogout', ['auth:api']);
    VRoute::setMiddleware('UserAPIController', 'GETShow', ['auth:api']);
    VRoute::setMiddleware('UserTaggingAPIController', 'PUTNotificationToggle', ['auth:api']);
    VRoute::setMiddleware('UserAPIController', 'GETChannels', ['auth:api']);
    VRoute::setMiddleware('ScoreAPIController', 'GETTotals', ['auth:api', 'acl']);
    VRoute::setMiddleware('PostAPIController', null, ['auth:api', 'acl']); //work for all versions
    
    VRoute::run(request());
  2. Procedural unity

  3. Team conventions

  4. More redable code in controller

    Before use Vroute:

    class UserAPIController extends AppBaseController
    {
        // some codes .....
        public function notification(): JsonResponse
        {
            //some codes
        }
    }

    After use VRoute:

    class UserAPIController extends AppBaseController
    {
        // some codes .....
        public function PUTNotification(): JsonResponse
        {
            //some codes
        }
    }

System requirements

Tested with >=7.1, following binaries need to be installed

Installation

composer require mehrdad-dadkhah/laravel-vroute

Usage

Put this code in your route file (for example routes/api.php)

use MehrdadDadkhah\VRoute;

VRoute::run(request());

That's it!

If you have sub-directory in you project, for example admin/client and .... should make them available for VRoute:

VRoute::setAvailableSubDirs([
'admin',
'client',
]);

How to set a middleware?

You can set middleware in 8 layers or ways!

  1. Set for controller in all version and directory

  2. Set for controller in specific directory (for example only for PostController in admin sub-dir)

  3. Set for controller in specific version (for example only for PostController in v2)

  4. Set for controller in specific directory and version (for example only for PostController in admin sub-dir and only version 1)

  5. Set for controller and specific action(method) (for example only for PostController and GETProfile action)

  6. Set for controller and specific action(method) in specific version (for example only for PostController and GETProfile action in V2)

  7. Set for controller and specific action(method) in specific directory (for example only for PostController and GETProfile action in admin sub-dir)

  8. Set for controller and specific action(method) in specific directory and version (for example only for PostController and GETProfile action in V2 and admin)

What about you set all 8 kind of middleware for one controller?

From top to bottom, if match the route, all middlewares will be merged.

For example we set:

  1. web1 middleware for PostController (without specify directory and version)

  2. web2 middleware for PostController for admin directory (without specify version)

  3. web3 middleware for PostController for v1 version (without specify directory)

  4. web4 middleware for PostController for admin directory and v1 version

Now we call /api/admin/v1/post, so all of the middlewares (web1,web2,web3,web4) will be fire

But If call /api/admin/post, only web1 and ```web2`` will be fire

Now, how to set it (middleware)?

First case (set for controller in all version and directory):

VRoute::setMiddleware('PostAPIController', null, ['web1']);

Second case (set for controller in specific directory):

VRoute::setMiddleware('PostAPIController', null, ['web2'], 'admin');

Third case (set for controller in specific version):

VRoute::setMiddleware('PostAPIController', null, ['web3'], null, 'v1');

Fourth case (set for controller in specific directory and version):

VRoute::setMiddleware('PostAPIController', null, ['web4'], 'admin', 'v1');

Second argument is action/method name

All of this can repeat for action case when set second param. for example:

VRoute::setMiddleware('PostAPIController', 'GETDetail', ['web1']);

and so on ...

Use VRoute methods and write your own specific route

You can get all data you need from VRoute functions:

VRoute::getControllerPath(request());

VRoute::getControllerName(request());

VRoute::getAction(request());

VRoute::getNamspace(request());

VRoute::getSubDirs(request());

For example:

$request = request();

Route::get('/post', VRoute::getNamspace($request).'@'.VRoute::getAction($request))->name('post-index');

Conventions

  1. All controller methods(actions) name should be with {HTTPMETHOD}{ActionName} template for example if you want have profile method that get user profile data, should name it GETProfile. this convention add to force action about it's method, force methods to response to only one type of http call method and make controller more readable.

To Do

  • Cache found routes
  • Add clean cache command
  • Add VRoute:cache command to iterate on controllers and cache all routes
  • Response cache feature

License

laravel-vroute is licensed under the GPLv3 License.

mehrdad-dadkhah/laravel-vroute 适用场景与选型建议

mehrdad-dadkhah/laravel-vroute 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 7 次下载、GitHub Stars 达 1, 最近一次更新时间为 2019 年 09 月 22 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「route」 「api」 「versioning」 「laravel」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 mehrdad-dadkhah/laravel-vroute 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 mehrdad-dadkhah/laravel-vroute 我们能提供哪些服务?
定制开发 / 二次开发

基于 mehrdad-dadkhah/laravel-vroute 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 7
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 4
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: AGPL-3.0-only
  • 更新时间: 2019-09-22