規範 API 介面錯誤響應格式

天衣有縫發表於2021-07-08

廢話不多說了,直接上程式碼。

定義 json 返回資料格式

首先定義一個 trait

app/Responses/ResponseJson.php

<?php
namespace App\Http\Responses;

trait ResponseJson
{
    private function jsonResponse($status, $code, $message, $data, $error)
    {
        $result = [
            'status'  => $status,
            'code'    => $code,
            'message' => $message,
            'data'    => $data,
            'error'  => $error,
        ];
        return response()->json($result);
    }

    public function jsonSuccessData($data)
    {
        return $this->jsonResponse('success', 200, '請求成功', $data, []);
    }

    public function jsonErrorsData($code, $message, $data = [])
    {
        return $this->jsonResponse('fail', $code, '請求失敗', $data, $message);
    }
}

統一的資料響應格式,固定包含:codestatusdatamessageerror

  • 成功直接呼叫 jsonSuccessData方法,傳入$data資料;
  • 失敗呼叫 jsonErrorsData 方法,傳入 $code$message$data, $data可以為空;

在基類控制器中引用

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Responses\ResponseJson;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;

class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests, ResponseJson;
}

修改 Handler 函式

App\Exceptions\Handler.php

<?php

namespace App\Exceptions;

use Throwable;

use App\Http\Responses\ResponseJson;

use Illuminate\Database\QueryException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Validation\ValidationException;
use \Symfony\Component\HttpKernel\Exception\HttpException;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    use ResponseJson;

    protected $dontReport = [
        //
    ];

    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    public function register()
    {
        $this->reportable(function (Throwable $e) {
            //
        });
    }

    // 新增以下方法
    public function render($request, Throwable $e)
    {
        $data = [];

        // 客戶端錯誤
        if ($e instanceof QueryException) {
            // 資料庫錯誤
            $code = 500;
            $message = '資料庫錯誤,請聯絡開發者';
            if (env('APP_DEBUG')) {
                $data = $e->getMessage();
            }

        }  else if ($e instanceof ValidationException) {
            // 驗證錯誤
            $code = 422;
            $message = '引數格式錯誤';
            $data = $e->errors();

        }  else if ($e instanceof HttpException) {
            // URL不正確
            $code = 404;
            $message = '未定義路由,請檢查 URL 是否正確';

        }  else if ($e instanceof AuthenticationException) {
            // token異常
            $code = 403;
            $message = 'token異常,禁止訪問';

        } else {
            // 其他異常
            $code = 500;
            $message = '伺服器異常';
            $data = $e->getMessage();
        }

        return $this->jsonErrorsData($code, $message, $data);
    }
}

程式碼說明:

  1. 首先 use 幾個檔案:

    • use Illuminate\Database\QueryException;
      這是用來捕獲資料錯誤的,例如:資料庫連線失敗,查詢欄位不存在等等;

    • use Illuminate\Auth\AuthenticationException;
      這是用來捕獲身份驗證錯誤的,例如:token過期;

    • use Illuminate\Validation\ValidationException;
      這是用來捕獲表單驗證錯誤的,例如:引數格式不對、引數缺失等等;

    • use \Symfony\Component\HttpKernel\Exception\HttpException;
      這是用來捕獲 http 請求異常的,例如:url不存在

      備註: 還有一些其他類用來捕獲其他型別的異常,請自行查詢,以上只列出常用的幾種異常捕獲

  2. rander函式中,用instanceof方法將$e判斷出是哪種錯誤,然後定義該種錯誤的狀態碼,獲取到錯誤資訊,然後返回給jsonErrorsData函式;

測試

  • 獲取資料列表介面:
    • 成功:
      {
        "status": "success",
        "code": 200,
        "message": "請求成功",
        "data": {
            "machine": "全部",
            "lately": "2021-07-09 15:59:40",
            "max": "[plc] 兩點尋邊功能已經啟用",
            "cnc": 0,
            "plc": 69,
            "count": 69
        },
        "error": ""
      }
    • 失敗:
      {
        "status": "fail",
        "code": 422,
        "message": "請求失敗",
        "data": {
            "machine": [
                "裝置 只能由字母、數字、短劃線(-)和下劃線(_)組成。",
                "裝置 不能為空。"
            ]
        },
        "error": "引數格式錯誤"
      }
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章