牛皮的程式猿後端返回值怎麼定義

JavaPub發表於2024-06-26

牛皮的程式猿後端返回值怎麼定義

《使用者中心》

在後端介面封裝中,我們一般都會對返回的資料做一個封裝,以防止系統出現不可預期的資料結構和型別。比如這樣:

結構體 1

{
  "success": true,
  "code": 200,
  "message": "成功",
  "data": {
    "items": [
      {
        "id": "1",
        "name": "小王",
        "identified": "JavaPub博主"
      }
    ]
  }
}

結構體 2

{
    "ret": 200,
    "data": {
        "title": "Default Api",
        "content": "王哥 您好,歡迎使用 apifather!",
        "version": "1.1.0",
        "time": 14231428021
    },
    "msg": ""
}

不論如何定義,多一個或少一個欄位,我們都需要統一規範。接下來我們拆解一下,

首先,透過觀察,一定要有狀態碼,也就是案例中的 coderet ,透過狀態碼可以知道當前程式哪裡出了問題,比如 200 就是成功。有同學會問,為何不用 data 來判斷,為空或者為 0 就是錯誤,當然不行。

比如:下面這個結構,data 長度雖然等於 0,但是這屬於確實沒查到資料,而不是程式出錯。

{
    "ret": 200,
    "data": [],
    "msg": ""
}

再看 data,這個毋庸置疑,它是介面的核心資料,也是介面對外提供的業務資料。

再看 message 或者稱為 msg,它是給狀態做一個文字說明。比如,有個老六在定義了一個狀態碼(666),第一次呼叫這個介面的同學可能並不知道返回的狀態碼含義、也不想去查介面文件,我加個描述:(老六的介面不通啦),呼叫者就一目瞭然了。

最後看 success 欄位,這個欄位是為了更規範而加的,方便前端直接將介面響應狀態展示。比如:使用者登入成功,可以展示一個 true,或者前端在判斷時也可以寫更簡潔的程式碼 if result.success:。畢竟將(老六的介面不通啦)描述直接展示出來顯得不太正式。

基於以上幾點,我們的返回結構這樣定義:

ApiResponse.class

// 定義API響應結構體
public class ApiResponse<T> {
    private int status; // HTTP狀態碼
    private String message; // 狀態資訊
    private T data; // 返回的資料,泛型支援返回不同型別的資料

    // 建構函式
    public ApiResponse(ResponseStatus status) {
        this.status = status.getCode();
        this.message = status.getMessage();
    }

    // 帶資料的建構函式
    public ApiResponse(ResponseStatus status, T data) {
        this(status);
        this.data = data;
    }

    // Getter和Setter方法
    // ...
}

定義完返回結構後,我們需要定義狀態的列舉值。這是為了定一個統一的規範,方便開發時狀態碼搞混。

// 定義狀態碼列舉
public enum ResponseStatus {
    SUCCESS(200, "操作成功"),
    ERROR(500, "伺服器內部錯誤"),
    BAD_REQUEST(400, "請求引數錯誤"),
    NOT_FOUND(404, "資源未找到"),
    UNAUTHORIZED(401, "未授權"),
    FORBIDDEN(403, "禁止訪問");

    private final int code;
    private final String message;

    ResponseStatus(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

如何使用呢

@GetMapping("/users/{id}")
public ResponseEntity<ApiResponse<User>> getUser(@PathVariable Long id) {
    try {
        User user = userService.getUserById(id);
        if (user != null) {
            return ResponseEntity.ok(new ApiResponse<>(ResponseStatus.SUCCESS, user));
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                                 .body(new ApiResponse<>(ResponseStatus.NOT_FOUND));
        }
    } catch (Exception e) {
        // 這裡可以根據異常型別返回不同的錯誤狀態碼和訊息
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                             .body(new ApiResponse<>(ResponseStatus.ERROR));
    }
}

這裡使用了 Spring 自帶的返回結構體 ResponseEntity 進行封裝。

獲取到的結果是這樣的:

{
  "code": 200,
  "message": "操作成功",
  "data": {
    "id": "1",
    "name": "javapub",
    "age": 18
  }
}

原文地址: https://javapub.net.cn/star/project/user-center/

相關文章