博客 / 詳情

返回

什麼是 RESTful API?憑什麼能流行 20 多年?

你是小阿巴,剛入職的後端程序員,負責給前端的阿花提供 API 接口。

結果一週後,你被阿花揍得鼻青臉腫。

阿花:你是我這輩子見過接口寫的最爛的程序員!

你一臉委屈找到號稱 “開發之狗” 的魚皮訴苦:接口不是能跑就行嗎?

魚皮嘲笑道:小阿巴,你必須得學學 RESTful API 了。

你撓撓頭:阿巴阿巴,什麼玩意,沒聽説過!

⭐️ 推薦觀看視頻版,動畫更生動:https://bilibili.com/video/BV1WFBXBmExs

 

什麼是 RESTful API?

魚皮:首先,REST 的全稱是 REpresentational State Transfer,翻譯過來叫 “表現層狀態轉移”。

你一臉懵:魚皮 gie gie,能説人話嗎?我是傻子,聽不太懂。

魚皮:別急,我給你拆開來講,保證你理解。

RE(Representational) 表現層,是指 資源(Resource) 的表現形式。

你好奇了:什麼是資源?

魚皮:資源就是 你想要操作的數據對象

比如用户、商品、文章,這些都是資源。用户列表是一個資源,某個具體的用户也是一個資源。

表現層是指資源呈現出來的具體格式,比如同一個用户資源,可以用 JSON 格式返回給客户端,也可以用 XML 格式返回,這就是不同的 “表現形式”。

S(State) 是指 “狀態”。

你:啥是狀態?

魚皮:比如你登錄網站後,服務器會在內存中記住 “你是誰”,之後在網站上操作就不用再次登錄了,這就是 有狀態

無狀態(Stateless) 呢,就是服務器不記錄客户端的任何信息,每次請求都是獨立的。

你:哦哦哦,就像一個人去餐廳吃飯,服務員不記得他上次點了什麼,每次都要重新點單,這就是無狀態。

反過來,服務員記得他愛吃魚皮,這就是有狀態。

魚皮:沒錯,接下來是 T(Transfer) 轉移。

要注意,轉移是 雙向 的:

1)當你用 GET 請求時,服務器把資源的狀態(比如用户信息的 JSON 數據)轉移給客户端。

2)當你用 POST/PUT 請求時,客户端把資源的新狀態(比如新用户的信息)轉移給服務器,從而改變服務器上資源的狀態。

組合起來,REST(Representational State Transfer) 是一種 軟件架構風格,讓客户端和服務器通過統一的接口,以無狀態的方式,互相傳遞資源的表現層數據(比如 JSON),來查詢或者變更資源狀態。

ful 是個後綴,就像 powerful(充滿力量的)一樣,表示 “充滿...特性的”。

因此,RESTful API 是指符合 REST 架構風格的 API,也就是遵循 REST 原則設計出來的接口。

注意,它 不是協議、不是標準、不是強制規範,只是一種建議的設計風格。你可以遵循,也可以不遵循。

你撓了撓頭:説了一大堆,RESTful API 到底長啥樣啊?

魚皮:舉個例子,比如你要做個用户管理系統,對用户信息進行增刪改查,用 RESTful 風格的 API 就長這樣:

GET /users/123       獲取 ID 為 123 的用户
POST /users         創建新用户
PUT /users/123       更新用户 123
DELETE /users/123   刪除用户 123

你眼前一亮:哇,比我寫的整齊多了!

快帶我學一下 RESTful 的寫法吧,我要讓前端阿花刮目相看!

 

RESTful API 寫法

魚皮:好,很有志氣!接下來我會帶你一步步構造一個完整的 RESTful API。分為兩部分,客户端發送請求服務端給出響應

客户端請求

第一步:確定資源

資源用 URI(統一資源標識符)來表示。核心原則是:用名詞來表示資源,不用動詞

具體來説,推薦用名詞複數表示資源集合,比如 /users 表示用户列表、/products 表示商品列表。

如果要操作 具體某個資源,就加上 ID,比如 /users/123 表示 ID 為 123 的用户。

資源還 支持嵌套,比如 /users/123/orders 表示用户 123 的所有訂單。

你想了想:那還可以更深層級麼?比如 /users/123/orders/456 表示用户 123 的訂單 456。

魚皮點點頭:你的理解完全正確,但不建議嵌套層級太深。

 

第二步:選擇動作

確定了資源後,接下來要選擇 動作,也就是你想怎麼處理這個資源。

RESTful API 主要通過不同的 HTTP 方法來表示增刪改查操作:

1)GET:查詢資源

  • GET /users 查詢所有用户

  • GET /users/123 查詢 ID 為 123 的用户

2)POST:創建資源

  • POST /users 創建新用户

3)PUT:完整更新資源,需要提供資源的所有字段,多次執行結果相同(冪等性)

  • PUT /users/123 完整更新用户 123

4)PATCH:部分更新資源,通常用於更精細的操作

  • PATCH /users/123 只更新用户 123 的某些字段

5)DELETE:刪除資源

  • DELETE /users/123 刪除用户 123

魚皮:到這裏,一個基本的 RESTful API 請求就構造完成了。

你:就這麼簡單?我不滿足,還有更高級的寫法嗎?

魚皮:當然~

 

第三步:添加查詢條件(可選)

有時候我們需要更精確地篩選數據,這時候可以加查詢參數,比如:

  • 分頁:/users?page=2&limit=10 查詢第 2 頁,每頁 10 條用户數據

  • 過濾:/users?gender=male&age=25 查詢性別為男、年齡 25 的用户

  • 排序:/users?sort=created_at&order=desc 按創建時間倒序排列用户

你:等等,這查詢參數跟 RESTful 有啥關係?正常的請求不都是這麼寫嗎?

魚皮:確實,查詢參數本身不是 RESTful 特有的。但 RESTful 風格強調 把篩選、排序、分頁這些操作,都通過 URL 參數來表達

而不是在請求體裏傳一堆複雜的 JSON 對象:

這樣一來,URL 更清晰,而且瀏覽器、CDN、代理服務器都能直接根據 URL 來緩存響應結果。比如 /users?page=1/users?page=2 是兩個不同的 URL,可以分別緩存。但如果把參數放在請求體裏,URL 都是 /users,緩存就沒法區分了。

 

第四步:版本控制(可選)

隨着業務發展,接口可能需要升級。為了不影響老用户,可以在 URI 中標明版本:

  • /v1/users 第一版用户接口

  • /v2/users 第二版用户接口

這樣,老用户繼續用 v1,新用户用 v2,互不影響。

 

第五步:保持無狀態

此外,還記得我們前面講 REST 裏的 ST(State Transfer) 嗎?

RESTful 的核心原則之一是 無狀態(Stateless),客户端每次請求必須包含所有必要信息,服務器不記錄客户端狀態。

比如用户登錄後,不是讓服務器記住 “你已經登錄了”,而是每次請求都要帶上身份憑證(Token),像這樣:

GET /orders
Header: Authorization: Bearer xxx

這麼做的好處是,服務器不用記錄誰登錄了、誰沒登錄,每個請求都是獨立的。這樣一來,你想加多少台服務器都行,任何一台都能處理請求,輕鬆實現負載均衡和橫向擴展。

你點頭如搗蒜:怪不得我調用 AI 大模型 API 的時候,就要傳這個 Token!

 

服務端響應

魚皮:講完客户端請求,再來看服務器收到請求後,該怎麼響應?

主要注意 2 點:

1、統一響應格式

目前大多數 RESTful API 基本都用 JSON 格式,因為輕量、容易解析。

{
 "id": 123,
 "name": "小阿巴",
 "email": "aba@codefather.cn"
}

但這並不是強制的,也可以用 XML、HTML 等格式。

 

2、返回合適的 HTTP 狀態碼

響應要帶上合適的狀態碼,讓客户端一眼看懂發生了什麼。

HTTP 狀態碼有很多,大體可以分為 5 類:

  • 1xx 系列:信息提示(用得少,瞭解即可)

  • 2xx 系列:成功

    • 200 OK:請求成功,正常返回數據(用於 GET、PUT、PATCH)

  • 3xx 系列:重定向

    • 301 Moved Permanently:資源永久移動到新位置

    • 302 Found:資源臨時移動

  • 4xx 系列:客户端錯誤

    • 400 Bad Request:請求參數格式錯誤

    • 401 Unauthorized:未驗證身份,需要登錄

    • 403 Forbidden:已認證但沒有權限訪問

    • 404 Not Found:資源不存在

    • 405 Method Not Allowed:請求方法不被允許

  • 5xx 系列:服務器錯誤

    • 500 Internal Server Error:服務器內部錯誤

    • 502 Bad Gateway:網關錯誤

    • 503 Service Unavailable:服務暫時不可用

    • 504 Gateway Timeout:網關超時

你恍然大悟:懂了,以後前端看到 500,就知道是我後端的鍋;看到 400,就知道是她自己傳參傳錯了。誰也別想甩鍋!

魚皮點點頭:不錯,以上這些,就是 RESTful API 的基本寫法。你學會了嗎?

你:學廢了,學廢了!

魚皮:那我來考考你,下面哪個是標準的 RESTful API?

  • A. GET /getUsers

  • B. GET /user/list

  • C. POST /users/query

  • D. GET /users/delete/123

你開心地怪叫起來:阿巴,肯定是 C 啊!

魚皮:錯,4 個全都不標準

  • A 用了動詞 getUsers

  • B 用了單數 user 和動詞 list

  • C 用 POST 查詢,還帶了動詞 query

  • D 用 GET 刪除,還帶了動詞 delete

你掉了根頭髮:原來這麼嚴格!

等等,你説 RESTful 不能用動詞,但有些操作不是標準的增刪改查啊,比如用户要支付訂單,該怎麼設計接口呢?是要用 POST /orders/123/pay

魚皮搖頭:你已經很努力了,但 pay 是動詞。更標準的設計是把 “支付” 行為看作 創建 一個支付記錄,用名詞而不是動詞。

POST /orders/123/payments

比如這個請求,表示為訂單 123 創建一筆支付記錄。

你又掉了根頭髮:妙啊,怪不得説英語對學編程有幫助呢,我悟了,我悟了!

 

RESTful 的六大約束

魚皮:不錯,學到這裏你已經掌握了 RESTful 的 80%,能夠實際應用了。接下來的知識,你只需簡單瞭解一下,就能拿去和麪試官吹牛皮了。

比如很多同學都不知道,RESTful 其實有 6 個約束條件:

  1. Client-Server(客户端-服務器分離):前後端各幹各的活,前端負責展示,後端負責數據處理,互不干擾。

  2. Stateless(無狀態):每次請求都是獨立的,服務器不保存客户端的會話信息,所有必要信息都在請求中攜帶。

  3. Cacheable(可緩存):服務器的響應可以被標記為可緩存或不可緩存,客户端可以重用緩存數據,減少服務器壓力,提升性能。

  4. Layered System(分層系統):客户端不需要知道直接連的是服務器還是中間層,系統可以靈活地加代理、網關、負載均衡器等。

  5. Uniform Interface(統一接口):所有資源都通過統一的接口訪問,降低理解成本,提高可維護性。

  6. Code-On-Demand(按需代碼):可選項,服務器可以返回可執行代碼(比如 JavaScript)給客户端執行,但實際工作中很少用。

你直接聽懵了:阿巴阿巴,這麼多約束,我必須全遵守嗎?

魚皮:可以不用,RESTful 只是一種 API 的 建議風格。在實際工作中,很少有 API 能完美符合所有約束,大家可以靈活調整,甚至什麼接口都用 POST + 動詞 一把梭。只要團隊達成一致、用得舒服就行。

就像剛才那個支付訂單的例子,POST /orders/123/payments 雖然符合 RESTful 規範,但有同學會覺得 POST /orders/123/pay 更直觀易懂,也沒問題。

不過現階段,我建議你先養成遵循 RESTful 的好習慣,等積累了經驗,再根據實際情況靈活調整。

 

怎麼快速實現 RESTful API?

你:嗚嗚,但我只是個小阿巴,背不下來這些寫法,我怕自己寫着寫着就不規範了,怎麼辦啊?

魚皮:別擔心,有很多方法可以幫你快速實現和檢查 RESTful API。

 

1、使用開發框架

幾乎所有主流開發框架都支持 RESTful API 的開發,它們能幫你自動處理很多細節,比如:

  • Java 的 Spring Boot:通過 @GetMapping("/users")@PostMapping("/users") 等註解,你只需要寫一行代碼就能定義符合 RESTful 風格的路由。框架會自動把對象轉成 JSON、設置正確的 HTTP 狀態碼,你都不用操心。

  • Python 的 Django REST Framework:你只需要定義一個數據模型(比如 User 類),框架就能自動生成 GET /usersPOST /usersPUT /users/123DELETE /users/123 這一整套 RESTful 接口,大幅減少代碼量。

  • Go 的 Gin :專門為 RESTful API 設計,語法非常簡潔。比如 router.GET("/users/:id", getUser) 就能綁定一個 GET 請求,自動從 URL 中提取 ID 參數,還能通過路由分組把 /api/v1/users/api/v2/users 輕鬆分開管理。

這些框架雖然不強制你遵循 RESTful,但用它們的特性,開發起來既輕鬆又規範,幫你省掉大量重複代碼。

 

2、使用 IDE 插件

比如 IDEA 的 RESTful Toolkit 插件,可以快速查看和測試接口。

 

還有 VSCode 的 REST Client 插件,可以直接在編輯器裏測試接口。

 

3、利用 AI 生成

RESTful 有明確的設計規範,而 AI 最擅長處理這種有章可循的東西!

比如直接讓 Cursor 幫你用 Spring Boot 寫一個用户管理的 RESTful API:

你只需要阿巴阿巴幾下,它就能生成規範的代碼。

 

4、生成接口文檔

寫完接口後,還可以用 Swagger 這類工具自動生成漂亮的接口文檔,直接甩給前端,對方一看就懂,還能在線測試接口,省去大量溝通成本。

你笑得像個孩子:這麼一看,RESTful API 不僅讓接口規範統一,還能提高開發效率,降低團隊溝通成本,前後端都舒服!爽爽爽!

魚皮點點頭:沒錯,這也是為什麼 RESTful 能成為業界主流的原因。

你:學會了學會了,我這就去重構所有接口,讓前端阿花刮目相看!

 

結尾

一週後,你把所有接口重構成了 RESTful 風格。

前端阿花打開新的接口文檔,眼睛亮了:小阿巴,你居然開竅了?!

你得意地笑了:那是,我可是學過 RESTful 的男人~ 阿花,晚上要不要一起?

阿花朝你吐了口唾沫:呸,你只不過學了一種 API 風格就得意洋洋。阿坤哥哥不僅精通 RESTful,還能手撕 GraphQL 和 gRPC 呢,你行麼?

你難受得不行:啥啥啥,這都是啥啊…… 魚皮 gie gie 快來救我!

 

更多編程學習資源

  • Java前端程序員必做項目實戰教程+畢設網站

  • 程序員免費編程學習交流社區(自學必備)

  • 程序員保姆級求職寫簡歷指南(找工作必備)

  • 程序員免費面試刷題網站工具(找工作必備)

  • 最新Java零基礎入門學習路線 + Java教程

  • 最新Python零基礎入門學習路線 + Python教程

  • 最新前端零基礎入門學習路線 + 前端教程

  • 最新數據結構和算法零基礎入門學習路線 + 算法教程

  • 最新C++零基礎入門學習路線、C++教程

  • 最新數據庫零基礎入門學習路線 + 數據庫教程

  • 最新Redis零基礎入門學習路線 + Redis教程

  • 最新計算機基礎入門學習路線 + 計算機基礎教程

  • 最新小程序入門學習路線 + 小程序開發教程

  • 最新SQL零基礎入門學習路線 + SQL教程

  • 最新Linux零基礎入門學習路線 + Linux教程

  • 最新Git/GitHub零基礎入門學習路線 + Git教程

  • 最新操作系統零基礎入門學習路線 + 操作系統教程

  • 最新計算機網絡零基礎入門學習路線 + 計算機網絡教程

  • 最新設計模式零基礎入門學習路線 + 設計模式教程

  • 最新軟件工程零基礎入門學習路線 + 軟件工程教程

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.