鑑於REST風格的Web服務都是基於「一切都以資源形式表示,並且可以通過地址(URI)訪問」的神聖思想,這對於CRUD應用程序可能是有意義的(所有示例都是關於列出/創建/更新/刪除實體)。但是,其他業務邏輯如何創建一個與CRUD操作無關的簡單計算器RESTful服務呢? 對於這樣的REST服務,什麼是一個好的設計?如何創建一個RESTful計算器?
其次,如果SOAP的邏輯已經完全有意義,那麼使用REST over SOAP的真正優勢是什麼?
鑑於REST風格的Web服務都是基於「一切都以資源形式表示,並且可以通過地址(URI)訪問」的神聖思想,這對於CRUD應用程序可能是有意義的(所有示例都是關於列出/創建/更新/刪除實體)。但是,其他業務邏輯如何創建一個與CRUD操作無關的簡單計算器RESTful服務呢? 對於這樣的REST服務,什麼是一個好的設計?如何創建一個RESTful計算器?
其次,如果SOAP的邏輯已經完全有意義,那麼使用REST over SOAP的真正優勢是什麼?
計算器服務可以很簡單地以REST風格進行建模。 「CRUD」中的「R」代表「閱讀」,沒有理由認爲「閱讀」也不意味着「計算」。因此,一個簡單的計算器Reverse Polish服務可以通過GET訪問:
GET https://calc.com/rpnCalc?3&4&%2B
7
上面簡單的URI方案增加了三個參數的GET請求:
3
4
+ (URL-encoded as %2B)
這是一個冪等,安全和緩存的請求。如果這是一個非常複雜的數學查詢,需要花費很多時間來計算,我可以將這些查詢路由到一個開箱即用的HTTP代理,並使用它來立即返回任何預先計算的值,如果重複查詢同一個URI。
根據您需要執行的計算類型,您還可以向Calculator資源發送非常複雜的查詢(將查詢作爲請求正文傳遞),並且服務器可能會將URI返回到「result」資源,然後您可以通過GET來檢索結果,甚至通過它們進行分頁。
其次,如果SOAP的 邏輯已經完全有意義,那麼使用REST而不是SOAP會有什麼真正的優勢?
我可以使用像curl這樣的命令行工具訪問上述計算器服務,而無需構建複雜的SOAP片段。我可以在幾秒鐘內對它進行編碼,而無需使用任何第三方XML庫或SOAP工具包。我可以使用諸如HTTP代理的商品工具來緩存結果並提高性能。我不必擔心SOAP互操作性或檢查WS-I的兼容性。如果我正確使用超鏈接,那麼我可以改進和改進我的服務,而不會影響現有的客戶端或讓他們甚至重新編譯。沒有WSDL版本,也沒有我必須維護多年的易碎合約。客戶端已經知道GET/PUT/POST/DELETE做了什麼,我不必重新定義或重新記錄它們的語義。決定他們更喜歡JSON而不是XML的API客戶端可以使用HTTP內置的內容協商功能。我可以絕對使用SOAP和Web服務來完成這些事情的零。
嘿,如果SOAP符合你的需求,那就去吧。使用REST有許多好處,但它們可能不適合您的情況。至少,瞭解REST可以給你一本體面的書like this one,然後在獲得完整故事後讓你記住它。
謝謝Brian!因此,如果方法也可以建模爲(子)資源,我也可以編寫「GET https://calc.com/arithmeticCalc/add?a=3&b=4」嗎? – karimyafi
是的,但我會避免添加動詞到您的URI結構。你在HTTP中已經有了動詞,所以你應該使用名詞來描述你的URI中的資源。這樣你的API客戶端就不會對如何使用每個資源感到困惑。想象一下你爲一個'/ add'資源做了一個HTTP'POST' - 我怎麼知道它是否會實際添加或創建一個子資源?爲了避免您的示例中出現混淆,我會稍微將其更改爲'calc.com/arithmeticCalc/adder?a = 3&b = 4'。 –
這是REST中名詞和動詞之間張力很好的例子。建議使用「添加」或「加法器」作爲資源是非常幼稚的。這意味着每個操作都可以通過GET方式完成「加法器」或「減法器」。當然可以讓資源「計算」,但我們使用動詞。我們可以將它改爲「計算器」或「答案」,它們都是名詞,但我們確實沒有做任何有用的事情。
HTTP POST不一定需要創建持久性資源。在RFC 2616, section 9.5我們發現:
POST方法執行的動作可能不會導致資源 可以通過URI標識。在這種情況下,200(OK)或204 (無內容)是合適的響應狀態,具體取決於 是否包含描述結果的實體。
這意味着我們可以考慮「創建計算」而不必在其自己的URL中保留計算結果。您的API可能看起來像這樣:
Request:
POST /calculations
Content-Type: text/plain
3 + 3/12^(3 * PI)
Response:
200 OK
Content-Type: text/plain
3.005454
這樣做,你不及格「內容」通過URL的好處,當你嘗試通過客戶端或代理有限長度提交長的計算,這將打破對於網址。您也可以爲請求和回覆支持不同的表示。
這個問題已經有幾年了。但似乎仍然有一個讓我和很多同事感到困惑的問題。我們無法達成滿足每個人的解決方案。
但是對於一個簡單的計算器,我認爲下面的JAXRS實現提供了一個乾淨的API。
/**
* This class defines a CalculatorResource.
*/
@Path("v{version}/calculators/{id}")
@Named
public class CalculatorResource {
private final Long value;
public CalculatorResource() {
value = 0L;
}
public CalculatorResource(Long initialValue) {
this.value = initialValue;
}
@GET
public Long getValue() {
return value;
}
@Path("+{value}")
public CalculatorResource add(@PathParam("value") Long value) {
return new CalculatorResource(this.value + value);
}
@Path("-{value}")
public CalculatorResource subtract(@PathParam("value") Long value) {
return new CalculatorResource(this.value - value);
}
@Path("*{value}")
public CalculatorResource multiply(@PathParam("value") Long value) {
return new CalculatorResource(this.value * value);
}
}
利用這種系統的實現中,URI可以是易於閱讀式。
例如,/api/v1/calculators/mycalc/+ 9/-4/* 3/+ 10 會返回25.
那麼究竟是什麼問題呢? – paulsm4