Laravel-自定义API返回的JSON格式
按照我司规范,服务器处理http请求后返回的JSON,应该是这样的格式:
{
code:
data:
msg:
}
这就需要对Laravel框架默认的返回值(太随意了,缺少一个统一的结构来包装返回值)做一些处理,具体包括以下几个部分:
(一)使用LaravelResponse Macro机制来自Controller的直接返回
需要进行以下几步操作:
1、创建一个ServiceProvider
php artisan make:provider ResponseMacroServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;
class ResponseMacroServiceProvider extends ServiceProvider
{
public function boot()
{
Response::macro('horesp', function ($code=2000, $data=null, $msg=null) {
$content = array(
'code' => $code,
'data' => $data,
'msg' => $msg
);
return response()->json($content);
});
}
public function register()
{
//
}
}
2、在config/app.php文件中的‘providers’列表中,增加下面的一行
App\Providers\ResponseMacroServiceProvider::class,
3、创建一个HOBaseController,以后所有的Controller都继承这个类
php artisan make:controller HOBaseController
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class HOBaseController extends Controller
{
//这个方法只应该在接口顺利完成了对请求业务的处理之后调用
public function response($data=null, $msg=null)
{
return response()->horesp(2000, $data, $msg);
}
}
4、以后在controller类里面直接返回结果时,使用这个方式
return $this->response($user->name);
(二)对主动返回的错误值做处理
原理是通过主动抛出异常,来处理所有需要返回错误代码和错误信息的情况,由框架的异常处理机制来构造最终的返回值。
1、创建一个HOException类
php artisan make:exception HOException
2、在App\Exception文件夹中,创建一个HOError.php文件,对每一个错误,都定义一个方法,供外部调用。
<?php
namespace App\Exceptions;
use \App\Exceptions\HOException as HOException;
class HOError
{
public function generalErr()
{
throw new HOException('General Error Occurred', 2001);
}
}
3、在HOBaseController里面,增加如下代码
protected $error;
public function error()
{
$this->error = new HOError();
return $this->error;
}
4、在App/Exeption/Handler.php文件中,重写render方法
use Illuminate\Support\Facades\Log;
use \App\Exceptions\HOException as HOException;
use Illuminate\Http\Exceptions\HttpResponseException;
public function render($request, Exception $exception)
{
//对详细的错误信息,进行记录,但是不返回给前端
Log::debug( parent::render($request, $exception) );
if ( $exception instanceof HOException ) {
$msg = $exception->getMessage();
}else{
$msg = 'Server Bad';
}
return response()->horesp( $exception->getCode(), null, $msg);
}
5、在Controller的方法里,可以这样来返回错误码和错误信息
return $this->error()->generalErr();
(三) 对Validate不通过的情况做处理
创建一个HOFormRequest类,继承FormRequest类,以后创建FormRequest,都从HOFormRequest类去集成. 解决方案来自:https://www.jianshu.com/p/658f979abfb7
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Exceptions\HOException as HOException;
use Illuminate\Contracts\Validation\Validator as Validator;
class HOFormRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
protected function failedValidation(Validator $validator)
{
$message = $validator->errors()->all();
throw new HOException(implode($message), 3000);
}
}
(四)对Authenticate不通过情况的处理
1、创建一个unauthenticated路由,在对应的controller方法中返回标准格式的错误信息和字符串给客户端。
Route::post('/user/unauthenticated', 'Api\UserController@unauthenticated')->name('unauthenticated');
2、修改app\middleware\authenticate.php中间件的redirectTo方法
protected function redirectTo($request){ return route('unauthenticated'); }