原文鏈接:https://https://howardwchen.com/2017/09/18/talk-about-restful-popular-api-design-1/
掃描文末二維碼,關注我的公眾號“就浩這口”,可在歷史消息中找到這篇文章的語音版。
(本文為“聊聊RESTful”系列文章第二篇,其他文章可通過篇尾鏈接查看)
大家好,歡迎大家來到“就浩這口”,今天我們繼續聊聊RESTful。
在我的上一篇文章科普篇中為大家介紹了REST的起源與REST成熟度模型。同時我也指出網上有大量介紹RESTful接口設計的文章,如果我們不理解真正的REST,那么單純的接口設計的討論會讓我們對REST產生誤解。那么在我們了解了什么是真正的REST之后,再來討論接口設計,就是學以致用。
所以,今天我們就來聊一聊RESTful的接口設計。我計劃分以下幾部分來介紹:
- URI命名
- HTTP方法
- 消息體格式
- 異常處理
- 版本化
- 鑒權
- 接口文檔
今天先來說說URI命名和HTTP方法。
URI命名
資源與名詞
了解RESTful接口的人都知道,URI的命名應該使用名詞,為什么呢?因為REST對于信息的核心抽象是資源,而表示資源的詞語天然的就是名詞,所以這不是什么技術問題,而是常識。
看似簡單的接口命名,其背后卻是REST當中核心的資源概念。學過面向對象編程的人們都知道這么一句話,萬物皆對象。類似的,對于REST則是,萬物皆資源。資源這一概念是在Fielding的論文中5.2.1.1小節來介紹的
5.2.1.1 Resources and Resource Identifiers
The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service (e.g. “today’s weather in Los Angeles”), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author’s hypertext reference must fit within the definition of a resource. A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time.
更詳細的介紹請大家閱讀論文。
不過相對于具體實踐,論文中對資源的描述還是相當抽象的,很多開發人員不知從何下手。我覺得,所謂資源的設計,在簡單項目中與我們傳統面向對象編程的設計沒有太大的區別。你要對你的需求做詳細的需求分析,劃分模塊,梳理流程,抽象出需求背后的邏輯關系,數據結構等。但是在規模更大,或者業務更復雜的系統中,傳統方式便顯得力不從心。這里我覺得DDD的理論完全可以作為資源設計的方法論。DDD本身就是為了解決復雜系統而設計的,它提供了多種模式與方法,幫助我們更好的分析需求,以及長期迭代系統。DDD不是本文的重點,我也還在學習中,這里不做更具體的說明了。以后我會做一個DDD的專題跟大家細說。
總之URI的命名,其背后就是對系統的整體設計。大家要做好充足的前期工作,避免生米煮成熟飯時悔之晚矣。
命名規則
命名規則永遠是一個具有爭議的話題,在RESTful接口中,對于URI一個普遍接受的規則是:全部小寫,用中劃線連接。
之所以不混用大小寫字母,是因為早期的URI一般都是表示服務器上的文件路徑,而不同服務器對大小寫的敏感性是不同的,為了兼容不同服務器所以才規定不能混用大小寫字母,然后用中劃線或下劃線連接多個單詞。
我們如今開發的api,URI一般不再表示服務器上的文件了,而是一種程序使用的路由,而各類開發程序對字符串的判斷也都是區分大小寫的,所以就算URI混用了大小寫一般也不會有問題。但是為了與那些仍舊表示服務器文件路徑的URI保持一致,更多的人仍舊愿意沿用全部使用小寫字母的規則。至于連接多個單詞使用中劃線還是下劃線,我只能說,中劃線使用得更加廣泛。
單數復數
在英文中,名詞是有單復數之分的,所以在對資源命名時究竟是用單數還是復數,這也成為了一個有爭議的問題。我在網上搜尋了很多相關資料,大部分人認為應該統一使用復數,但我在這里有不同的看法,我的使用習慣是,用單數來表示單個資源,用復數來表示集合資源。我們先來看下網上關于使用復數的說法:
1. 阮一峰的網絡日志《RESTful 設計指南》
在RESTful架構中,每個網址代表一種資源(resource),所以網址中不能有動詞,只能有名詞,而且所用的名詞往往與數據庫的表格名對應。一般來說,數據庫中的表都是同種記錄的"集合"(collection),所以API中的名詞也應該使用復數。
這篇文章寫于2014年,這段話中的數據庫的表格名,我理解指的是mysql這類的關系型數據庫的表名。我在科普篇中也提到過,基于資源的架構設計是不同于基于關系型數據的設計的,關系型數據庫的數據結構和資源結構是不能完全對應的,所以作者這里用了往往一詞,因為現實中確實有很多人在這么做,但嚴格來講,一個良好的資源設計,是很難和關系型數據庫一一對應上的。因此我并不贊同作者說的因為數據庫中的表都是同種記錄的"集合"(collection)而推導出我們的資源命名應該使用復數。另一方面,我們仔細想一下,我們給數據庫表命名時可是很少用復數的啊,上網搜下數據庫表名命名規則,同樣有很多的爭論,但我相信,你見過的單數要更多。而面向對象的開發中,對象的命名也大都是單數,集合變量的命名才使用復數。當然,所有這些情況其實都暗含著集合的含義,也許我們都用該用復數,可實際情況并非如此。
2. Best Practices for Designing a Pragmatic RESTful API及其譯文
Should the endpoint name be singular or plural? The keep-it-simple rule applies here. Although your inner-grammatician will tell you it's wrong to describe a single instance of a resource using a plural, the pragmatic answer is to keep the URL format consistent and always use a plural. Not having to deal with odd pluralization (person/people, goose/geese) makes the life of the API consumer better and is easier for the API provider to implement (as most modern frameworks will natively handle /tickets and /tickets/12 under a common controller).
這篇文章提供了兩點理由:
- keep-it-simple,作者說盡管你知道使用復數來表示單個資源是錯誤的,但是這樣更簡單,更務實,并且不用處理怪異的復數形式。這點我很不理解,難道符合常識的做法不是更簡單更務實的嗎?英語中已然有了單復數的區分,可我們卻只用復數,我覺得這才是比較怪異的。對于作者提到的怪異的復數形式,雖然存在,但畢竟是少數單詞,對于精通英語的外國人來說,應該并不是什么問題。按照DDD的思想,軟件的建模應該發生在在真實世界的問題得到解決之后,因此我并不贊同為了開發軟件而對語法做不必要的改變。
- 接口易于實現,作者說大多數現代框架天然地將/tickets和/tickets/12放在同一個控制器下處理,我并不知道這里指的是什么框架,我查了下作者的github,是以Ruby語言為主的,我并不了解這門語言。在Java開發中,我們大都使用SpringMVC或者基于JAX-RS的框架來做web開發,URI與控制器的對應關系都是我們手動維護的,并不存在作者所謂的天然,因此我也并不贊同作者的這個理由。
3. RESTful API Design Tips from Experience及譯文
Use Plurals
It makes semantic sense when you request many posts from/posts
.
And for goodness sake don’t consider/post/all
with/post/:id
.// plurals are consistent and make sense
GET
/v1/posts/:id/attachments/:id/comments
// don't consider ambiguity
// is it just one comment? is it a form? etc.
GET
/v1/post/:id/attachment/:id/comment
“I like the idea of using plurals for resource names, but sometimes you get names that can’t be pluralised.”
In cases like these you should simply try to get as close to plural as you can!
說實話我并沒有理解作者的困惑,如果用comment來表示評論的集合那確實會有歧義,但如果用來表示單條評論則完全沒有問題,難道用posts來表示概念上的帖子或者單個帖子時就沒有歧義嗎?我記得在英語中,表示抽象概念的大都是不可數名詞。而且以上這段節選中作者還引用了一段評論,并建議在不能使用復數的時候盡可能使用復數,我覺得這種違背一般認知的方法更容易引起歧義。
網上多數支持使用復數的文章,大都是轉載的以上三篇文章,還有一些文章只是支持使用復數,但并沒有給出原因,我也便無法給出評價。除此之外,在很多論壇或問答網站中(如Stack Overflow)也找到了一些關于此話題的討論,他們討論的內容似乎比一些文章更有價值,因為每個人都在論述自己所支持的觀點的原因,而不僅僅是表述自己的觀點,比如這個十年前的帖子《終于知道rails單復數的規則了?!?/a>。
下面我來說下我自己的觀點:用單數來表示單個資源,用復數來表示集合資源。在資源的設計中我們比較容易達成的共識是,資源分為兩大類,單個資源和集合資源,仍以圖書為例,我會將URI設計為:單個資源/book/:id
,集合資源/books
。原因有以下下幾點
- 符合英語單復數的使用習慣,多數情況下,符合習慣的才是簡單的容易理解的。
- 單個資源和集合資源的差異其實是很大的,集合資源中的單個元素的表述,與單個資源的表述是不同的,有時甚至差異很大(集合資源中往往還會包含分頁信息)。所以我更愿意將單個資源和集合資源當做兩種完全不同的資源來對待,這樣也便避免了單復數的混淆。很多文章都主張避免單復數混用,我理解它的原意應該是要避免單復數形式與資源類型的混亂,所以只要我們嚴格按照單數與單個資源匹配,復數與集合資源匹配,這種混亂也是可以避免的。
關于兩類資源的差異,我們舉個例子,單本圖書的表述可能包括書名、ISBN、作者、出版社、出版日期、印張數、圖書簡介、作者簡介、目錄、樣張、封面圖等等很多很多信息,而對于圖書列表,每個元素中可能只包括書名、作者、價格。也就是說我們在服務端處理時完全可以用兩個不同的類來表示單本圖書和圖書列表中的一個元素,而不是僅僅為了復用一個實體類代碼而混用一個類,進而造成兩種資源概念的耦合。當然,如果是個簡單的資源,復用一個類也是完全沒有問題的,但這并不影響我們區分對待單個資源和資源集合。因此,既然我把兩種資源區分對待,那么再參考理由1,我覺得用單數來表示單個資源,用復數來表示集合資源就是合理的了。
其實在我的觀點中,關注的重點并不是單數與復數的區別,而是單個資源與集合資源的區別。
當然,對于單復數的討論,我并不認為有什么絕對正確的結論,一切都要結合實際情況具體分析,只要你的理由合理充分,就可以大膽使用。以上是我的個人觀點,有興趣討論的小伙伴可以在下方留言。
HTTP方法
常用的方法有GET
, POST
, PUT
, DELETE
,此外有時還會用到HEAD
、PATCH
和OPTION
。前面說我們系統的設計是以資源為核心的,URI的命名要使用名詞,那我們要如何來表示一個操作動作呢?就是依靠HTTP方法,也叫HTTP動詞。也就是通過這種動名詞的組合來表示一次操作,在REST中會被叫做狀態轉移。
簡單的講GET
是查詢操作,不會產生狀態轉移, PUT
和PATCH
是更新操作,會將資源狀態轉移為客戶端期望的新的狀態,也有可能是一個從無到有的轉移, DELETE
表示刪除,將資源狀態轉移為刪除,POST
表示添加一個資源,即資源狀態從無轉移到有,另外POST
也被認為是一個萬能的方法,可以用于所有的操作,包括寫操作和復雜的查詢操作。
四種常用方法與CRUD
很多人都會認為,四種常用方法就是對應數據庫的增刪改查,但這只是REST應用于一些簡單業務的表象而已。前面說了,REST是以資源為核心的,四種常用方法所操作的對象也是資源,對資源的操作是狀態轉移,數據的增刪改查則是持久層的具體實現,一次狀態轉移可能會對應多個數據庫表的添加修改刪除操作,所以他們之間沒有嚴格的一一對應關系。以后講具體實現時如果有相關例子,再給大家細說。
安全、冪等、可緩存
在2014年最新修訂的HTTP1.1規范中HTTP方法有三個通用屬性:安全、冪等、可緩存。下表給出了常見方法的安全性和冪等性,可緩存性是根據實際情況決定的。我們在設計接口時,要考慮到這些屬性。
HTTP方法 | 安全性 | 冪等性 |
---|---|---|
GET | 是 | 是 |
POST | 否 | 否 |
PUT | 否 | 是 |
DELETE | 否 | 是 |
HEAD | 是 | 是 |
PATCH | 否 | 否 |
安全性
4.2.1. Safe Methods
Request methods are considered "safe" if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. Likewise, reasonable use of a safe method is not expected to cause any harm, loss of property, or unusual burden on the origin server.
安全性比較容易理解,只讀的就是安全的,所以很多非REST系統中,使用GET方法來提交數據的方式就是違背規范的。也就是說我們在設計實現具有安全性的HTTP方法時(如GET),一定要保證資源狀態不變。
冪等性
4.2.2. Idempotent Methods
A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. Of the request methods defined by this specification, PUT, DELETE, and safe request methods are idempotent.
冪等性是我想重點介紹的,因為有很多人甚至沒聽過這個概念。我們可以簡單的用一個數學公式來表示冪等性:
f(f(x)) = f(x)
也就是說同一個操作,執行一次和執行多次的效果是一樣的。這里的效果指的是我們使用某方法后達到的預期的資源狀態。
要說冪等性,就要說下REST的適用范圍,Fielding的論文對其討論范圍做了限定,大家可以查看原文或譯文了解更多詳情
2.1 Scope
Architecture is found at multiple levels within software systems. This dissertation examines the highest level of abstraction in software architecture, where the interactions among components are capable of being realized in network communication. We limit our discussion to styles for network-based application architectures in order to reduce the dimensions of variance among the styles studied.
對于網絡應用(network-based application),它與集中式應用最大的不同在于,我們要充分考慮網絡的不可靠性,我們要把網絡異常當做一種常規用例來處理,最常見的處理方式就是重試。而冪等性的意義就在于,如果一個方法是冪等的,那么在出現網絡異常而導致請求失敗時,我們可以對此請求進行重試,而不必擔心引起預期外的結果。而對于不具有冪等性的請求,就不能僅通過重試來處理網絡異常了。例如,一個POST請求超時了,我們并不知道服務端是否接收到了請求,如果我們此時進行重試,很有可能會向服務器添加多個資源。
因此,在接口設計中,我們要盡量將接口設計為冪等的,以便調用方可以更方便地處理異常情況。對于規范中定義的冪等的HTTP方法,我們必須將其實現為冪等的,而對于像POST這類非冪等的方法,我們其實也可以盡力設計為對重試友好的。我們還用圖書舉例,添加一本圖書信息時,如果ISBN是全局唯一的,我們可以根據此字段對添加的信息做唯一性校驗,這樣就可以避免同一請求多次提交時創建多個資源了。當然,調用方在處理請求響應時可能需要考慮201 Created
和400 Bad Request
兩種情況。
稍等一下,上面圖書的例子中,既然可以重試,那這樣的設計是冪等的嗎?我們注意到,如果圖書信息添加成功則返回201 Created
,如果是多次提交導致了唯一約束沖突則返回400 Bad Request
,一次提交和多次提交的響應是不同,這算冪等嗎?我覺得規范中定義的冪等,關注的是預期效果,它指的應該是資源狀態,而非響應內容。例如,DELETE請求,我們的預期效果是將目標資源的狀態變為刪除,因此不管是一次請求響應204 No Content
,還是再次請求響應404 Not Found
,資源狀態都已經變為刪除,也便達到了我們的預期,這就是冪等的。因此響應的不同,并不是判斷是否冪等的標準。標準只有一個,就是看執行一次和執行多次的效果是否一樣。
那么我們再來看上面圖書的例子,是冪等的嗎?它不是冪等的,因為在這種情況下,客戶端無法判斷資源狀態是否符合預期。比如,當第一次請求超時后,客戶端進行重試,然后得到400 Bad Request
的響應,提示失敗原因是違反ISBN唯一約束,此時客戶端無法判斷服務端已存在的資源是剛剛自己添加的,還是之前就已經存在的,如果是之前已經存在的,那它的狀態可能和自己期望添加后的狀態是不同的,客戶端可能還需要額外的操作才能判斷,或者根本無法判斷,我想這樣的情況是不能稱為冪等的。盡管如此,這樣的設計仍能避免多次請求導致重復添加資源的情況,這也是有意義的。有時我可以通過用PUT請求來表示添加資源的方式來解決類似問題,下文中會有詳細說明。
可緩存性
4.2.3. Cacheable Methods
Request methods can be defined as "cacheable" to indicate that responses to them are allowed to be stored for future reuse; for specific requirements see [RFC7234]. In general, safe methods that do not depend on a current or authoritative response are defined as cacheable; this specification defines GET, HEAD, and POST as cacheable, although the overwhelming majority of cache implementations only support GET and HEAD.
我在科普篇中提到過,REST架構風格是由多個架構風格疊加而成,而緩存風格($)就是其中之一。緩存不是本文重點,這里不做過多解釋,只是希望大家了解其在REST架構風格中的地位。參考規范定義,多數情況下,我們在設計接口時要考慮到GET或HEAD甚至POST響應的內容是有可能被客戶端緩存的就好。
POST與PUT
講冪等性時,我說添加圖書信息的例子可以用PUT來解決。也就是說PUT也可以用來添加資源,它和POST的區別就是PUT具有冪等性,所以只有當客戶端可以決定資源唯一標識的時候才可以使用PUT添加資源。比如前面添加圖書信息的例子中,如果ISBN就是圖書信息的唯一標識(現實中往往并非如此,這里僅為了舉例),那么客戶端完全可以使用PUT方法來添加圖書信息,從而獲得冪等性帶來的好處。現實中,服務端使用關系型數據庫來存儲圖書信息時,往往會用自增主鍵做唯一標識,但是如果這個自增主鍵對客戶端無意義的話,我們可以不對客戶端暴露此屬性,僅讓客戶端以ISBN作為資源唯一標識就好。
PUT與PATCH
PATCH方法在早期的HTTP1.1規范RFC2068出現過,但是在修訂版RFC2616中卻不見蹤影,而是在RFC5789中單獨做了定義。其中原委我就不太清楚了,如果誰知道還請多多賜教。
按照規范中的說明,PUT用于資源的整體更新,而PATCH用于局部更新,這個局部更新并不僅僅是局部替換,也包括了追加,所以PATCH既不安全也不冪等。
因為PATCH是在擴展規范中定義的,所以對它的支持并不是很廣泛。也有一些人認為應該盡量避免使用PATCH。我在實際工作中也是使用PUT來實現局部更新的。那么這里我們來討論以下兩個問題:
- PUT是否可以用于局部更新。
- PATCH如何實現局部更新。
PUT是否可以用于局部更新
網上可以找到很多對于此問題的討論,其中stack overflow的一篇問答帖"Why isn't HTTP PUT allowed to do partial updates in a REST API?",我覺得很不錯,我們來看一看。
這篇問答帖中被標記為接受的答案直接請出了REST的作者Fielding博士,引用了他在twitter上回復別人的一段話
Who says? The guy who invented REST says:
@mnot Oy, yes, PATCH was something I created for the initial HTTP/1.1 proposal because partial PUT is never RESTful. ;-)
引用的對話中,IETF HTTP和QUIC工作組的聯合主席Mark說,有種說法很可笑,是說某些HTTP擴展規范并不RESTful,而這些擴展規范恰恰就是Fielding本人參與制定的,于是就跟Fielding有了一段對話,上面引用的就是Fielding最后的回復。這樣看來REST作者本尊直接給PUT用于局部修改判了死刑。但仔細想想,會發現一個問題,Fielding這里說的RESTful指的是什么呢?還記得我在科普篇中提到Fielding發表的"REST must be hypertext"嗎?Fielding這里說的RESTful應該是指REST成熟度模型的第3級,超媒體驅動的RESTful。而我們開發的RESTful api遠遠達不到這個水平。所以,你可以因為Fielding的觀點而不使用PUT實現局部更新,完全沒問題,但這個理由我覺得并不充分。
除了被接受的答案外,還有一個票數為-4的答案
Partial updates are allowed by PUT (according to RFC 7231 http://tools.ietf.org/html/rfc7231#section-4.3.4).
",... PUT request is defined as replacing the state of the target resource." - replacing part of object basically change state of it.
"Partial content updates are possible by targeting a separately identified resource with state that overlaps a portion of the larger resource, ..."
According to that RFC next request is valid: PUT /resource/123 {name: 'new name'} It will change only name for specified resource. Specifying id inside request payload would be incorrect (as PUT not allow partial updates for unspecified resources).
票數-4說明大家并不認可他的觀點,因為他對RFC規范理解錯了,那么我們就來看一下他引用的HTTP1.1規范中介紹PUT時一段關于局部修改的這段說明:
Partial content updates are possible by targeting a separately identified resource with state that overlaps a portion of the larger resource, or by using a different method that has been specifically defined for partial updates (for example, the PATCH method defined in RFC5789).
這里給出了兩個實現局部更新的方法:
- 將一個較大的資源中的各部分,分別設計為單獨的資源,使用PUT進行更新。這種方式實際上是把主體資源拆解成了更細粒度的資源,然后對細粒度資源做整體更新,以達到局部更新的效果,本質上并未改變PUT的語義。
- 使用一個專門為局部更新設計的方法來做更新,比如RFC5789定義的PATCH。
同時,在RFC5789中也有一段對PUT的描述:
The PUT method is already defined to overwrite a resource with a complete new body, and cannot be reused to do partial changes. Otherwise, proxies and caches, and even clients and servers, may get confused as to the result of the operation.
好了,既然HTTP1.1規范以及PATCH擴展規范給出明確的說明,那么看來用PUT來實現局部更新確實是不可取的。盡管如此,我們仍能找到很多贊成使用PUT實現局部更新的觀點,比如文章"REST API Best Practices 3: Partial Updates - PATCH vs PUT"的觀點:
REST purists insist that PATCH is the only "correct" way to perform partial updates, but it hasn't reached "best-practice" status just yet, for a number of reasons.
Pragmatists, on the other hand, are concerned with building mobile back-ends and APIs that simply work and are easy to use, even if that means using PUT to perform partial updates.
綜上,我來說說我自己的觀點。正如前文所說HTTP相關規范已經明確指出PUT不適用于局部更新,那么這個觀點我是贊成的。但是考慮到一個實際情況是,我們設計開發的api往往RESTful程度并不高,遠遠達不到Fielding定義的,或者HTTP規范中所說的那種程度,那么我覺得也就沒必要過分追求與規范的嚴格匹配了,畢竟這種事在行業內太常見了。
不過,就算你不嚴格按規范設計,那也不能胡來,也要有一些約束。理解REST理念,理解規范要求以及他們所帶來的好處,還是很有必要的,比如冪等性。在理解了這些的基礎上,就算你結合自身實際決定用PUT來實現局部更新,你也會在設計時考慮很多約束,至少PUT的冪等性是不能破壞的。
如果你最終決定遵守規則,要用PATCH來實現局部更新,那你就要好好了解下PATCH的規范了,確保自己真的知道如何實現。
PATCH如何實現局部更新
我相信,那些使用PATCH來實現局部更新的接口,大都采用了一種類似于PUT的實現方式。客戶端請求消息體中帶有局部的資源表述,而服務端處理請求時,只會更新這個局部資源表述中涉及到屬性。但嚴格來講這里也會有一些問題。在RFC5789中,對PATCH的實現有這樣的描述:
The difference between the PUT and PATCH requests is reflected in the way the server processes the enclosed entity to modify the resource identified by the Request-URI. In a PUT request, the enclosed entity is considered to be a modified version of the resource stored on the origin server, and the client is requesting that the stored version be replaced. With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version.
它說PATCH的消息體應該包含一組指令,它描述了當前屬于遠程服務器的資源要如何被修改,以生成一個新的版本。也就是說PATCH請求的消息體中,并不是局部的資源表述,而應該是一組描述如何修改的指令。這樣一來,我們直接提交一個局部資源表述的方式就顯得不太符合規范了。而這里說的這組指令的媒體類型也跟表示資源的媒體類型應該有所不同。
規范說的比較抽象模糊,實踐中RFC7396定義了一種實現方式"JSON Merge Patch"。這個規范基于Json定義了一種新的媒體類型application/merge-patch+json
來表示修改指令,而表述的形式則與我們常用方式相似。雖然都是Json格式,但是如果媒體類型只是application/json
,嚴格來講是不符合規范的。因為單純的Json格式并沒有表示局部修改的語義,我們實現時完全是服務端定制化的邏輯,這顯然是非RESTful的。所以這份規范中定義了一種能夠表示修改指令的媒體類型,用于支持PATCH更新。這也是REST中統一接口風格的一種體現。
總的來說RFC7396是一個既能滿足規范,又很符合我們實際期望的,淺顯易懂的實現方式。在它發布之前,學術界建議的實現方式是RFC6902。這個規范就要更加復雜一些了,不過卻可以支持某些特殊的操作,比如move
,而這類操作RFC7396就有心無力了。
今天就跟大家聊到這里了,歡迎大家掃描下方二維碼,關注我的公眾號“就浩這口”,收聽這篇文章的語音版解說,并持續關注后續內容。下一期我將繼續為大家介紹接口設計的后面兩點內容,消息體格式及異常處理,我們下期再見。
傳送門
- 聊聊RESTful - 科普篇
- 聊聊RESTful - 接口設計篇(一)
- 聊聊RESTful - 接口設計篇(二)(消息體格式)