背景
最近在學(xué)習(xí)開發(fā)一個(gè)安卓項(xiàng)目,后端接口項(xiàng)目開始用PHP的Yii2.0框架新啟了個(gè)項(xiàng)目,后換成laravel5.5,最近看到laravel升級(jí)了新版本,于是又將項(xiàng)目更新到laravel6.4
在使用yii和laravel的過程中,兩個(gè)框架對(duì)web-api都非常友好,也都對(duì)restful做了不同程度的支持,但是還是遇到了一些問題,下面以laravel6.4為例,簡單描述下我遇到的問題。
問題一:訪問接口返回頁面代碼
最典型的就是laravel new 一個(gè)項(xiàng)目后,在瀏覽器直接訪問localhost會(huì)進(jìn)入laravel框架模版的默認(rèn)歡迎頁,這個(gè)沒有太大的問題,問題就是你用postman把這個(gè)地址當(dāng)接口
調(diào)用,返回的就是頁面的代碼,你在安卓端調(diào)用返回的還是頁面的代碼,其實(shí)實(shí)際使用不會(huì)去調(diào)用/跟接口,但是調(diào)用接口的時(shí)候一些其他的錯(cuò)誤比如4xx,5xx都會(huì)返回html代碼。
安卓端只能通過判斷狀態(tài)碼來判斷請(qǐng)求的成功失敗,而且極難拿到錯(cuò)誤信息。其實(shí)這里可以在安卓端統(tǒng)一加header,但是...... 于是網(wǎng)上查了下怎么處理
第一種辦法解決postman調(diào)試的是可以在postman的請(qǐng)求中設(shè)置headers X-Requested-With:XMLHttpRequest來模擬ajax請(qǐng)求
第二種辦法使項(xiàng)目僅返回JSON格式的需要新建一個(gè)Middleware
namespace App\Http\Middleware;
use Closure;
class JsonApplication
{
public function handle($request, Closure $next)
{
$request->headers->set('Accept', 'application/json');
return $next($request);
}
}
然后在Kernel中全局注冊(cè)Middleware并應(yīng)用所有的api請(qǐng)求(這里因?yàn)轫?xiàng)目是web-api項(xiàng)目,所以將routes/api.php的namespace去掉了,所以$middlewareGroups
中的key是api)
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
protected $middlewareGroups = [
'api' => [
......
'json_application',
],
];
protected $routeMiddleware = [
......
'json_application' => \App\Http\Middleware\JsonApplication::class,
];
}
這樣配置好后就再也不用擔(dān)心調(diào)用接口,給你返回的是頁面代碼。
問題二: 接口返回統(tǒng)一的JSON格式
通過上面的配置接口返回?cái)?shù)據(jù)都是JSON的格式了,但是繼續(xù)開發(fā)會(huì)發(fā)現(xiàn),還是需要通過HTTP狀態(tài)碼來判斷是否成功,然后返回的JSON里面的key不同的接口差異特別大,即使同一個(gè)接口在成功和出錯(cuò)的時(shí)候也會(huì)返回不同的KEY。
這個(gè)問題多采用返回同一格式的問題,由于之前給vue寫過很多接口,所以還是沿用之前的key的模式
{
"code": "0",
"msg": "ok",
"data": ""
}
但是在laravel中怎么返回這個(gè)格式成了一個(gè)問題,網(wǎng)上查了好幾次,都沒有太好的解決辦法,多是覆蓋的情況不全,再有就是錯(cuò)誤碼錯(cuò)誤信息都寫在邏輯層,新加的完全不知道有沒有沖突。
后來又在BD和GG搜索好久,自己也嘗試用laravel自帶的異常機(jī)制和Middleware處理,始終不是太滿意。
用過JAVA的都知道,在java中處理錯(cuò)誤碼很方便,直接定義一個(gè)枚舉把所有的錯(cuò)誤代碼都寫在里面,拋出異常的時(shí)候枚舉當(dāng)做參數(shù)傳遞進(jìn)去。類似于這樣
枚舉
package *.*.*
public enum ErrorCode {
OK("ok", 0),
PARAM_ERROR("param error", 88888),
UNKNOWN_ERROR("unknown error", 99999);
ErrorCode(String value, Integer key) {
this.value = value;
this.key = key;
}
private String value;
private Integer key;
public String getValue() {
return value;
}
public Integer getKey() {
return key;
}
}
異常類
package *.*.*;
import *.*.*.ErrorCode;
public class ApiException extends Exception {
public int code = 0;
public ApiException(ErrorCode errorCode) {
super(errorCode.getValue());
this.code = errorCode.getKey();
}
......
}
使用
throw new ApiException(ErrorCode.UNKNOWN_ERROR);
于是查了下PHP的枚舉,還真支持,但仔細(xì)一研究才發(fā)現(xiàn),PHP的枚舉不僅要安裝開啟SPL,然而提供的方法也并沒有什么卵用
于是仿照J(rèn)AVA寫了一個(gè)
基類
namespace App\Enums;
abstract class Enum
{
public static function __callStatic($name, $arguments)
{
return new static(constant('static::' . $name));
}
}
錯(cuò)誤碼 這里因?yàn)橛玫搅四g(shù)方法,所以要在注視中標(biāo)注
namespace App\Enums;
/**
* @method static CodeEnum OK
* @method static CodeEnum ERROR
*/
class CodeEnum extends Enum
{
public const OK = ['0', 'ok'];
public const ERROR = ['99999', 'fail'];
private $code;
private $msg;
public function __construct($param)
{
$this->code = reset($param);
$this->msg = end($param);
}
public function getCode()
{
return $this->code;
}
public function getMsg()
{
return $this->msg;
}
}
自定義異常類
namespace App\Exceptions;
use App\Enums\CodeEnum;
use Exception;
use Illuminate\Support\Facades\Log;
class ApiException extends Exception
{
public function __construct(CodeEnum $enum)
{
parent::__construct($enum->getMsg(), $enum->getCode());
}
public function report()
{
Log::error("ApiException {$this->getFile()}({$this->getLine()}): code({$this->getCode()}) msg({$this->getMessage()})");
}
public function render($request)
{
return response([
'code' => $this->getCode(),
'msg' => $this->getMessage(),
'data' => ''
]);
}
}
調(diào)用
throw new ApiException(new CodeEnum(CodeEnum::ERROR)); // 這樣調(diào)總感覺不太好看
throw new ApiException(CodeEnum::OK()); // 這樣調(diào)用和java的調(diào)用方式就很像了
總結(jié)
以上所述是小編給大家介紹的laravel返回統(tǒng)一格式錯(cuò)誤碼問題,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
您可能感興趣的文章:- Laravel手動(dòng)返回錯(cuò)誤碼示例