版權聲明:轉載時請以超鏈接形式標明文章原始出處和作者信息及本聲明http://phoenixtoday.blogbus.com/logs/45855234.html
最近小組里有一些關于REST API設計的討論,有些收獲,打算在這里寫一下。通常來講設計第一個版本的REST API并不難,難點在于將來你要改變了這些API,而客戶那里已經有對應的客戶端實現, 那么你怎么保證兼容?或者,至少,你應當讓這些東西失效吧,這樣客戶才能知道。所以基本上就是兩個問題。
1,在最初設計時,如何盡量保證向后兼容?(這里不提倡過度設計噢,我們是搞敏捷的,哈哈)
2,如果API發生了改變,該怎么通知已有實現?
對于第一個問題,答案相對而言簡單一些:支持必要的,但是最少的東西,而且層次不要太多。為什么?用下面的xml,舉個例子來說
<person>
<name>phoenix</name>
<job>softerware developer</job>
<company>ThoughtWorks</company>
</person>
第一層,指的是這個xml具體針對什么,第二層有三個屬性,分別是name,job和company,這是一個嵌套層次很好的,而且也沒有包含過多的信息。但是如果我們在一開始再加上address屬性(假設它并非必要),那么如果客戶構建了一個客戶端也的確包含了address屬性,那么在下一個版本的API中,你把這個屬性去掉了。問題是不是出現了?客戶的軟件無法工作了。反過來,如果最開始的版本不包含address,但是有客戶強烈要求下一個版本要支持,那么怎么辦?簡單!在下一個版本加上就好了,對于已有的客戶端,多一行冗余數據而已,也不會導致客戶的軟件無法工作。好了,這個問題解決了,那么,什么是嵌套層次不要太多。舉個反例
<person>
<name>phoenix</name>
<job>softerware developer</job>
<company>
<name>ThoughtWorks</name>
<locations type="array">
<city>beijing</city>
<city>san francisco</city>
</locations>
<products>
<product>
<name>mingle</name>
</product>
<product>
<name>cruise</name>
</product>
<product>
<name>twist</name>
</product>
</products>
</company>
</person>
這叫層次太多!一個company里,包含了太多的嵌套信息,其中location還算說的過去(因為只是一個簡單的數組),但是products里包含了子對象就不對了,這就是第三層對象了,具體的解決方案可以利用url來替換掉。世界終于清靜啦!
可是我還不能清靜,因為要回答第二個問題:API改變了,該怎么通知已有實現?這是一個很頭疼的問題,如果能避免回答我絕對會避免,可惜,不能!通常有兩種解決方案,但目的都是為了讓客戶的軟件失效(我知道,我知道,這會讓客戶抓狂,可是我們也沒轍啊!所以還是能不動,則不動,打死也不動,打不死嘛......就按如下辦)a,使用帶有版本號的API URL(這是現在最經常使用的一種方法),例如api/v2/projects/members.xml前面的api不說也明白,v2就是version 2版本2的意思,如果更換了,就變v3,客戶的軟件不能用了,也就知道了;b,利用HTTP header 里的ACCEPT來解決(別說你寫了這么多年程序,連HTTP有HEAD都不知道啊!會被鄙視的!),ACCEPT可以設置接受的文件,你可以將版本信息放在里面。技術細節不多說了,給個鏈接,供大家參考 http://barelyenough.org/blog/2008/05/versioning-rest-web-services/ 其實我是比較贊成這種方式的,比較優雅,但缺點就是它還不是標準,對方的程序員也可能不知道HTTP有HEAD,所以做起來,對人家可能會有點復雜,這里就不再多說了。
總之昵~~,小初(想必盯我博客很久的人,也都知道我姓甚名誰了,以后我就用真名了)的技術博客在沉寂了,這么久之后,又回來了(我胡XX又回來啦!哈哈),有太多東西要寫了,以后會陸續帶給大家的,多謝捧場!
PS:為啥Blogbus不支持<pre>標簽呢,讓我的xml這么丑的出現在博客里?慚愧呀!
轉載于:https://www.cnblogs.com/hnrainll/archive/2011/08/16/2140445.html