SuperAPI AI Directory

api-design-safety

Coding & development

View repository

Updated 10-15 21:11

About this skill

API Design Security Guidelines

When designing or modifying REST API response structures, prevent common design flaws.


Pitfall #1: Generic Method Overload Ambiguity

Scenario: When the return type is String, Java overload resolution may match the wrong method

Root Cause

During Java method overload resolution,String type parameters will preferentially match success(String message) rather than success(T data), causing data to enter the wrong field.

Incorrect Example

// ApiResponse 有两个重载:
public static <T> ApiResponse<T> success(T data)
public static <T> ApiResponse<T> success(String message, T data)

// ❌ 错误: String 类型匹配到 success(String message)
String avatarUrl = "http://example.com/avatar.jpg";
return ApiResponse.success(avatarUrl);
// 结果: {"code":200, "message":"http://...", "data":null}
// 前端 data.data 拿到 null,导致功能异常

Correct Approach

// ✅ 方案1: 明确指定 message 参数(推荐)
return ApiResponse.success("上传成功", avatarUrl);
// 结果: {"code":200, "message":"上传成功", "data":"http://..."}

// ✅ 方案2: 使用泛型明确类型
return ApiResponse.<String>success(avatarUrl);

// ✅ 方案3: 包装为 DTO(复杂场景推荐)
return ApiResponse.success(new UploadResult(avatarUrl));

Checklist

  • When returning the String type, is the message parameter explicitly specified
  • Are there overloaded methods with one parameter and two parameters
  • Does the frontend correctly parse the data field (rather than message)
  • Are there unit tests to verify the response structure

Pitfall #2: Unclear Response Field Semantics

Scenario: message and data field responsibilities are confused

Specification

Field Purpose Type Example
code Business status code int 200, 400, 500
message User-readable prompt message String "Upload successful", "Invalid parameters"
data Business data T {"url": "..."}, [...]
timestamp Response timestamp String ISO 8601 format

Incorrect Example

// ❌ 错误: 把业务数据放在 message
return ApiResponse.success("avatars/2026-04/xxx.jpeg");

// ❌ 错误: message 包含技术细节
return ApiResponse.error("NullPointerException at line 42");

Correct Approach

// ✅ message 是用户提示,data 是业务数据
return ApiResponse.success("上传成功", avatarUrl);

// ✅ 错误信息对用户友好
return ApiResponse.error("文件格式不支持,请上传 JPG/PNG 格式");

Pitfall #3: Inconsistent Null Handling

Scenario: Return when there is no data null、{}、[] is not consistent

Specification

Scenario Recommended Return Description
Single object does not exist data: null Frontend checks if (!data)
Empty list data: [] Frontend can iterate directly
Empty paginated data data: {list: [], total: 0} Maintain consistent structure

Incorrect Example

// ❌ 错误: 有时返回 null,有时返回空对象
if (user == null) {
    return ApiResponse.success(null);  // 不一致
}
return ApiResponse.success(new UserVO());

Correct Approach

// ✅ 统一返回 null 表示不存在
if (user == null) {
    return ApiResponse.success(null);
}
return ApiResponse.success(userVO);

// ✅ 列表统一返回空数组
List<UserVO> users = userService.list();
return ApiResponse.success(users);  // 永远不返回 null

Pitfall #4: Confusing HTTP Status Codes with Business Status Codes

Scenario: Return HTTP 500 when business fails

Specification

Scenario HTTP Status Code Business code Description
Success 200 200 Normal response
Parameter error 200 400 Business layer validation failed
Unauthorized 401 - Authentication failed
No permission 403 - Authorization failed
Resource does not exist 200 404 Business resource does not exist
Server error 500 - Code exception

Incorrect Example

// ❌ 错误: 业务失败返回 HTTP 500
if (user == null) {
    throw new RuntimeException("用户不存在");  // HTTP 500
}

Correct Approach

// ✅ 业务失败返回 HTTP 200 + 业务 code
if (user == null) {
    return ApiResponse.error(404, "用户不存在");  // HTTP 200
}

// ✅ 只有代码异常才返回 HTTP 500
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResponse<?>> handleException(Exception e) {
    log.error("服务器错误", e);
    return ResponseEntity.status(500)
        .body(ApiResponse.error("服务器错误,请稍后重试"));
}

Checklist (API Design)

Return Value Design:

  • When returning the String type, is the message parameter explicitly specified
  • message Does the field contain only user-readable prompt messages
  • data Does the field contain only business data
  • Is null handling consistent (null / [] / {})

Status Code Design:

  • Are HTTP status codes used only for the transport layer (200/401/403/500)
  • Is the business status code in the response body's code field
  • Does business failure return HTTP 200 + business code

Frontend-backend protocol:

  • Does the frontend correctly parse the data field
  • Does the frontend handle the data: null case
  • Is there API documentation or interface testing

Scope of application

  • Java: Spring Boot REST API
  • Go: Gin/Echo REST API
  • Node.js: Express/Koa REST API
  • Python: FastAPI/Flask REST API

Rule traceability

> 📋 本回复遵循:`api-design-safety` - API 设计安全规范