是否有人对于每次写一个laravel的控制器都要在路由上写一堆的声明路由感到麻烦,后期维护又不好处理,这里总结下如何让自己写出的接口更加规范格式化,本人在laravel项目中使用了dingo/api

  1. .env上配置dingo的配置信息
#Dingo API
API_PREFIX=api
API_VERSION=v1
API_DEBUG=true
  1. 在route.php的路由方法中添加这几行代码
$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api) {
    $api->any('{slug}', '\App\Http\ApiRouter@route')->where('slug', '(.*)?');
});
  1. 封装统一入口ApiRouter.php
use App;
use Dingo\Api\Routing\Helpers;
use Illuminate\Routing\Controller;
use Illuminate\Support\Str;
use core\util\router\RouterHelper;

class ApiRouter extends Controller
{
    use Helpers;

    private $ns;

    const API_NS = 'core\bapi';
    function __construct($ns)
    {
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods:*');
        header('Access-Control-Allow-Headers:*');
        $this->ns = $ns;
    }

    /**
     * @var string Allows early access to page action.
     */
    public static $action;

    /**
     * @var array Allows early access to page parameters.
     */
    public static $params;

    /**
     * 调试模式在.env设置API_DEBUG=true会有出错跟踪,不设置的话返回500的一般格式错误
     */
    public function route($url = null)
    {
        $API_SUBTYPE=env('API_SUBTYPE', '');
        $params = RouterHelper::segmentizeUrl($url);
        if(isset($_SERVER['HTTP_ACCEPT'])&&preg_match("/x.{$API_SUBTYPE}.v([\d]+)\+json/",$_SERVER['HTTP_ACCEPT'],$matches)) {
            //dingo api 的判断版本方式,以header头部的Accept来判断的
            define("API_VERSION",$matches[1]);
        }elseif ($params[0] == 'v2') {
           array_shift($params);
           define("API_VERSION",2);
        }else{
           define("API_VERSION",1);
        }
        /*
         * Look for a Api controller
         */
		$testPathDeep = 0;
		if (isset($params[2]))
		{
			$testPathDeep = 1;
			$api = $params[0] ."\\". Str::ucfirst($params[1]) ;
		}
		else
		{
          $api = isset($params[0]) ? $params[0] : null;
		}
        $api = Str::ucfirst($api).'Api';
        $apiClass = $this->ns."\\".$api;
        // 是否测试类
        
        if (env('APP_DEBUG') && $params[0] == 'test') {
            $api = isset($params[1]) ? $params[1] : null;
            $api = Str::ucfirst($api).'Test';
            $apiClass = $this->ns."\\test\\".$api;
            $testPathDeep = 1;
        }
        if (is_null($api)) {
            return $this->response->errorNotFound('api not exist ');
        }
        self::$action = $action = isset($params[$testPathDeep+1]) ? $this->parseAction($params[$testPathDeep+1]) : null;
        self::$params = $controllerParams = array_slice($params, $testPathDeep+2);

        if (!class_exists($apiClass)) {
            return $this->response->errorNotFound('api path not exist ' . (env('APP_DEBUG') ? $apiClass : ''));
        } else {
            $controllerObj = App::make($apiClass);
            if (!$action) $action = 'index';
            if ($controllerObj->actionExists($action)) {
                return $controllerObj->handle($action, $controllerParams);
            } else {
                return $this->response->errorNotFound('api command not exist ' . (env('APP_DEBUG') ? $action : ''));
            }
        }
    }

    /**
     * Process the action name, since dashes are not supported in PHP methods.
     * @param  string $actionName
     * @return string
     */
    protected function parseAction($actionName)
    {
        if (strpos($actionName, '-') !== false) {
            return camel_case($actionName);
        }

        return $actionName;
    }
}
  1. 以上环境部署完成后,文件结构如有 /api/UserApi.php 此时如访问/api/user/info 即可访问到相应的类和方法下了 /api/User/ActionApi.php => /api/user/action/create