是否有人对于每次写一个laravel的控制器都要在路由上写一堆的声明路由感到麻烦,后期维护又不好处理,这里总结下如何让自己写出的接口更加规范格式化,本人在laravel项目中使用了dingo/api
- .env上配置dingo的配置信息
#Dingo API
API_PREFIX=api
API_VERSION=v1
API_DEBUG=true
- 在route.php的路由方法中添加这几行代码
$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api) {
$api->any('{slug}', '\App\Http\ApiRouter@route')->where('slug', '(.*)?');
});
- 封装统一入口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;
}
}
- 以上环境部署完成后,文件结构如有 /api/UserApi.php 此时如访问/api/user/info 即可访问到相应的类和方法下了 /api/User/ActionApi.php => /api/user/action/create