在傳統前後端分離開發中,接口定義、文檔維護、版本兼容、聯調溝通消耗了大量研發資源。APIJSON 作為一種 JSON 傳輸結構協議,通過「所求即所得」的設計理念,徹底消除了固定接口與文檔的必要性。本文深度解析 APIJSON 核心機制、優勢場景、權限控制與安全防護。
| 傳統 REST API 痛點 | APIJSON 解決方案 |
|---|---|
| 接口定義僵化,需求變更頻繁改接口 | 客戶端定義請求結構,服務端動態解析,無固定接口 |
| 文檔滯後/錯誤導致聯調反復 | 無需文檔,請求即文檔,響應結構與請求鏡像 |
| 多頁面聚合需多次請求/後端聚合接口 | 一次請求任意結構任意數據,支持嵌套關聯查詢 |
| 數據冗餘 (列表中重復用戶信息) | 自動去重,客戶端聲明引用關係,服務端自動合併 |
| 版本兼容需維護多版本接口 | 服務端攔截器統一處理,無版本接口概念 |
| 前後端並行開發阻塞 | 前端自行構造請求編寫解析,完全解耦 |
{
"[]": { // 請求一個數組
"page": 0, // 分頁參數
"count": 10,
"User": { // 請求 User 表,返回 User 對象
"id": 1,
"@column": "id,name,head" // 指定返回列
},
"Post[]": { // 請求 Post 數組
"page": 0,
"count": 5,
"userId": "User/id" // 依賴引用:關聯 User.id
}
}
}
{
"[]": [
{
"User": {
"id": 1,
"name": "Tommy",
"head": "https://..."
},
"Post[]": [
{ "Post": { "id": 101, "content": "Hello", "userId": 1 } },
{ "Post": { "id": 102, "content": "World", "userId": 1 } }
]
}
]
}
// 請求:用戶 + 其發帖列表 (帖子中不重復用戶信息)
{
"User": { "id": 1 },
"Post[]": {
"count": 10,
"userId": "User/id" // 從同級 User 對象引用 id
}
}
// 響應:用戶信息僅出現一次,帖子引用 userId
{
"User": { "id": 1, "name": "Tommy" },
"Post[]": [
{ "Post": { "id": 101, "content": "...", "userId": 1 } },
{ "Post": { "id": 102, "content": "...", "userId": 1 } }
]
}
{
"User": { "id": 1 },
"Post[]": {
"count": 3,
"userId": "User/id",
"Comment[]": { // 帖子下的評論
"count": 2,
"postId": "[]/Post/id" // 完整路徑引用:從數組根節點查找
}
}
}
{
"User[]": {
"count": 10,
"User": {
"age@>": 18, // 年齡大於 18
"age@<": 60,
"name@$": "Tom", // 模糊匹配包含 "Tom"
"status@[]": [1,2], // IN 查詢
"createDate@>=": "2023-01-01"
}
}
}
// 請求頭傳遞身份憑證
{
"currentUserId": 100,
"loginPassword": "123456",
"payPassword": "888888",
"User": { "id": 1 }
}
// 服務端權限驗證器 (簡化版)
public class AccessVerifier {
public static void verify(JSONObject request, String tableName) throws AccessException {
int accessLevel = getAccessLevel(tableName);
if (accessLevel < 0) return; // 無需權限
Long userId = request.getLong("currentUserId");
if (userId <= 0) throw new AccessException("未登錄");
switch (accessLevel) {
case LOGIN_ACCESS:
if (!passwordMatches(userId, request.getString("loginPassword")))
throw new AccessException("登錄密碼錯誤");
break;
case PAY_ACCESS:
if (!passwordMatches(userId, request.getString("payPassword")))
throw new AccessException("支付密碼錯誤");
break;
}
}
private static int getAccessLevel(String tableName) {
// 配置表權限等級:User/Post 需登錄,Wallet 需支付權限
if (Arrays.asList("User", "Post").contains(tableName)) return LOGIN_ACCESS;
if ("Wallet".equals(tableName)) return PAY_ACCESS;
return -1;
}
}
客戶端請求 (JSON)
│
▼
┌──────────────────┐
│ HTTP 服務器 │
│ (Tomcat/Netty) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ APIJSON 解析器 │ ◄── 核心組件
│ 1. 解析請求結構 │
│ 2. 構建 SQL 查詢 │
│ 3. 執行數據庫操作 │
│ 4. 組裝響應 JSON │
│ 5. 權限/邏輯攔截 │
└────────┬─────────┘
│
▼
數據庫 (MySQL/PostgreSQL/Oracle...)
| 特性 | REST API | GraphQL | APIJSON |
|---|---|---|---|
| 接口定義 | 固定端點/參數 | Schema 定義 | 無接口,請求即定義 |
| 文檔維護 | Swagger/OpenAPI | Schema 即文檔 | 無需文檔 |
| 數據獲取 | 多請求/聚合接口 | 單請求聲明式 | 單請求聲明式 + 自動去重 |
| 學習成本 | 低 | 中 (Schema/Resolver) | 低 (直觀 JSON) |
| 後端實現 | Controller/Service | Resolver 函數 | 零代碼 (配置/攔截器) |
| 權限控制 | 攔截器/注解 | 指令/中間件 | 統一驗證器 |
<dependency>
<groupId>com.apijson</groupId>
<artifactId>apijson-orm</artifactId>
<version>2023.09.01</version> <!-- 檢查最新版本 -->
</dependency>
# Spring Boot 整合
@SpringBootApplication
@Import(ApiJsonConfig.class)
public class Application { ... }
# 配置數據源、權限驗證器、SQL 攔截器等
APIJSON 代表了一種 「以數據為中心,接口隱形化」 的架構演進方向。它不一定完全取代 REST/GraphQL,但在 「前端主導、後端賦能、快速迭代、多端復用」 的場景下極具競爭力。核心價值在於:將接口定義權還給客戶端,將數據組裝邏輯下沉到框架層,讓業務代碼回歸純粹的領域邏輯。
項目地址:https://github.com/TommyLemon/APIJSON (歡迎 Star/Fork)
文檔教程:項目 Wiki 包含完整語法手冊、部署指南、最佳實踐