如何設計REST API
分段學習REST是一回事,而將所有這些學到的概念應用到實際應用程序設計中則完全是另一挑戰。在本教程中,我們將學習爲基於網絡的應用程序設計REST API。請注意,整個練習的主要內容是學習如何在設計過程中應用REST原理。
- 設計REST服務的步驟
- 識別對象模型
- 創建模型URI
- 確定表示形式
- 分配HTTP方法
- 更多操作
識別對象模型
設計基於REST API的應用程序的第一步是–確定將作爲資源呈現的對象。
對於基於網絡的應用程序,對象建模要簡單得多。可以有很多東西,例如設備,管理實體,路由器,調制解調器等。爲簡單起見,我們將僅考慮兩個資源,即
- 設備
- 構型
這裏的配置是設備的子資源。設備可以具有許多配置選項。
請注意,我們上面的模型中的兩個對象/資源都將具有唯一的標識符,這是integer id
屬性。
創建模型URI
現在,當對象模型準備就緒時,就該確定資源URI了。在此步驟中,在設計資源URI時 -着重於資源及其子資源之間的關係。這些資源URI是RESTful服務的端點。
在我們的應用程序中,設備是頂級資源。而配置是設備下的子資源。讓我們寫下URI。
/devices
/devices/{id}
/configurations
/configurations/{id}
/devices/{id}/configurations
/devices/{id}/configurations/{id}
請注意,這些URI不使用任何動詞或操作。在URI中不要包含任何動詞非常重要。URI都只能是名詞。
確定製圖表達
現在確定了資源URI後,讓我們開始研究它們的表示形式。通常,表示形式以XML或JSON格式定義。我們將看到XML示例在表達數據構成方面更具表現力。
設備資源收集
返回收集資源時,僅包括有關資源的最重要信息。這將使有效負載的大小保持較小,因此將提高REST API的性能。
<devices size="2">
<link rel="self" href="/devices"/>
<device id="12345">
<link rel="self" href="/devices/12345"/>
<deviceFamily>apple-es</deviceFamily>
<OSVersion>10.3R2.11</OSVersion>
<platform>SRX100B</platform>
<serialNumber>32423457</serialNumber>
<connectionStatus>up</connectionStatus>
<ipAddr>192.168.21.9</ipAddr>
<name>apple-srx_200</name>
<status>active</status>
</device>
<device id="556677">
<link rel="self" href="/devices/556677"/>
<deviceFamily>apple-es</deviceFamily>
<OSVersion>10.3R2.11</OSVersion>
<platform>SRX100B</platform>
<serialNumber>6453534</serialNumber>
<connectionStatus>up</connectionStatus>
<ipAddr>192.168.20.23</ipAddr>
<name>apple-srx_200</name>
<status>active</status>
</device>
</devices>
單設備資源
與集合URI相反,此處在此URI中包含設備的完整信息。在這裏,還包括子資源和其他支持的操作的鏈接列表。這將使您的REST API HATEOAS驅動。
<device id="12345">
<link rel="self" href="/devices/12345"/>
<id>12345</id>
<deviceFamily>apple-es</deviceFamily>
<OSVersion>10.0R2.10</OSVersion>
<platform>SRX100-LM</platform>
<serialNumber>32423457</serialNumber>
<name>apple-srx_100_lehar</name>
<hostName>apple-srx_100_lehar</hostName>
<ipAddr>192.168.21.9</ipAddr>
<status>active</status>
<configurations size="2">
<link rel="self" href="/configurations" />
<configuration id="42342">
<link rel="self" href="/configurations/42342" />
</configuration>
<configuration id="675675">
<link rel="self" href="/configurations/675675" />
</configuration>
</configurations>
<method href="/devices/12345/exec-rpc" rel="rpc"/>
<method href="/devices/12345/synch-config"rel="synch device configuration"/>
</device>
配置資源收集
與設備集合表示類似,僅使用最少的信息即可創建配置集合表示。
<configurations size="20">
<link rel="self" href="/configurations" />
<configuration id="42342">
<link rel="self" href="/configurations/42342" />
</configuration>
<configuration id="675675">
<link rel="self" href="/configurations/675675" />
</configuration>
...
...
</configurations>
請注意,configurations
內部的集合表示device
類似於頂級configurations
URI。唯一的區別是,configurations
一個設備只有兩個,因此只有兩個配置項被列爲設備下的子資源。
單一配置資源
現在,單個配置資源表示必須具有有關該資源的所有可能信息-包括相關鏈接。
<configuration id="42342">
<link rel="self" href="/configurations/42342" />
<content><![CDATA[...]]></content>
<status>active</status>
<link rel="raw configuration content" href="/configurations/42342/raw" />
</configuration>
單個設備下的配置資源收集
配置的此資源集合將是配置的主要集合的子集,並且僅特定於設備。由於它是主集合的子集,因此請勿創建與主集合不同的表示形式數據字段。使用與主要集合相同的表示字段。
<configurations size="2">
<link rel="self" href="/devices/12345/configurations" />
<configuration id="53324">
<link rel="self" href="/devices/12345/configurations/53324" />
<link rel="detail" href="/configurations/53324" />
</configuration>
<configuration id="333443">
<link rel="self" href="/devices/12345/configurations/333443" />
<link rel="detail" href="/configurations/333443" />
</configuration>
</configurations>
請注意,此子資源集合具有兩個鏈接。
一個用於直接在子集合中表示,即/devices/12345/configurations/333443
,
另一個指向其在主要集合中的位置,即/configurations/333443
。
具有兩個鏈接非常重要,因爲您可以以更獨特的方式提供對設備特定配置的訪問,並且您將能夠屏蔽某些字段(如果設計需要),這些字段在輔助集合中不可見。
單個設備下的單個配置資源
此表示應具有與主集合中的Configuration表示完全相同的表示;或者,您可能會掩蓋一些字段。
此子資源表示形式還將具有指向其主要表示形式的附加鏈接。
<configuration id="11223344">
<link rel="self" href="/devices/12345/configurations/11223344" />
<link rel="detail" href="/configurations/11223344" />
<content><![CDATA[...]]></content>
<status>active</status>
<link rel="raw configuration content" href="/configurations/11223344/raw" />
</configuration>
現在,在進入下一部分之前,讓我們記下一些觀察結果,以免您錯過它們。
- 資源URI都是名詞。
- URI通常採用兩種形式-資源收集和單一資源。
- 收集可以採用兩種形式:一次收集和二次收集。次要集合是僅主要集合中的子集合。
- 每個資源/集合至少包含一個鏈接,即指向自身的鏈接。
- 集合僅包含有關資源的最重要信息。
- 要獲取有關資源的完整信息,您僅需要通過其特定的資源URI進行訪問。
- 表示形式可以具有額外的鏈接(即單個設備中的方法)。這裏
method
代表一個POST方法。您也可以以全新的方式擁有更多屬性或形成鏈接。 - 我們還沒有談論這些資源上的操作。
分配HTTP方法
因此,我們的資源URI及其表示形式現已修復。讓我們確定應用程序中可能的操作,並將這些操作映射到資源URI。網絡應用程序的用戶可以執行瀏覽,創建,更新或刪除操作。因此,讓我們對其進行映射。
瀏覽所有設備或配置[主集合]
HTTP GET /devices
HTTP GET /configurations
如果集合很大,則也可以應用分頁和過濾。例如,下面的請求將從集合中獲取前20條記錄。
HTTP GET /devices?startIndex=0&size=20
HTTP GET /configurations?startIndex=0&size=20
瀏覽所有設備或配置[次級集合]
HTTP GET /devices/{id}/configurations
這主要是一個小規模的集合-因此無需在此處啓用過濾或篩選。
瀏覽單個設備或配置[主集合]
要獲取設備或配置的完整詳細信息,請GET
對單個資源URI 使用操作。
HTTP GET /devices/{id}
HTTP GET /configurations/{id}
瀏覽單個設備或配置[次級集合]
HTTP GET /devices/{id}/configurations/{id}
子資源表示將與主要表示相同或相同。
創建設備或配置
創建不是冪等操作,並且在HTTP協議中- POST
也不是冪等。因此,請使用POST。在REST API的上下文中,發出多個相同的請求與發出單個請求具有相同的效果–然後將該REST API稱爲冪等
HTTP POST /devices
HTTP POST /configurations
請注意,請求有效負載將不包含任何id
屬性,因爲服務器負責決定它。創建請求的響應將如下所示:
HTTP/1.1 201 Created
Content-Type: application/xml
Location: http://example.com/network-app/configurations/678678
<configuration id="678678">
<link rel="self" href="/configurations/678678" />
<content><![CDATA[...]]></content>
<status>active</status>
<link rel="raw configuration content" href="/configurations/678678/raw" />
</configuration>
更新設備或配置
更新操作是冪等操作,HTTP PUT
也是冪等方法。因此我們可以使用PUT方法進行更新操作。
HTTP PUT /devices/{id}
HTTP PUT /configurations/{id}
PUT響應可能如下所示。
HTTP/1.1 200 OK
Content-Type: application/xml
<configuration id="678678">
<link rel="self" href="/configurations/678678" />
<content><![CDATA[. updated content here .]]></content>
<status>active</status>
<link rel="raw configuration content" href="/configurations/678678/raw" />
</configuration>
刪除設備或配置
刪除始終是一項DELETE
操作。
HTTP DELETE /devices/{id}
HTTP DELETE /configurations/{id}
成功的響應應該是202 (Accepted)
資源是否已排隊刪除(異步操作),或者200 (OK)
/ 204 (No Content)
如果資源已永久刪除(同步操作)。
在異步操作的情況下,應用程序應返回一個任務ID,該任務ID可以跟蹤成功/失敗狀態。
*請注意,當從系統中刪除子資源時,您應該進行足夠的分析以確定行爲。通常,您可能希望在這些請求中“ **軟刪除”*資源-換句話說,將其狀態設置爲“不活動”。通過遵循這種方法,您也無需在其他地方查找和刪除其引用。
從設備應用或刪除配置
在實際應用程序中,您將需要在設備上應用配置–或者您可能希望從設備(而不是從主集合中)刪除配置。在這種情況下,由於其冪等性質,應使用PUT和DELETE方法。
// Apply Configuration on a device
HTTP PUT /devices/{id}/configurations
//Remove Configuration on a device
HTTP DELETE /devices/{id}/configurations/{id}