学习REST是件好事,而将所有学到的概念应用到实际应用程序设计中则完全是另一项挑战。在本教程中,我们将学习为基于网络的应用程序设计REST API。请注意,整个练习的内容是学习如何在设计过程中应用REST原则。
设计REST服务的步骤
识别对象模型
创建模型URI
确定表示形式
分配HTTP方法
更多操作
googletag.cmd.push(function() { googletag.display('waldo-tag-4084'); });
设计基于REST API的应用程序的第一步是 - 识别将作为资源呈现的对象。
对于基于网络的应用程序,对象建模非常简单。可能有许多东西,如设备,管理实体,路由器,调制解调器等。为简单起见,我们将只考虑两个资源,即
这里配置是设备的子资源。设备可以有许多配置选项。
请注意,上述模型中的两个对象/资源都将具有唯一标识符,即整数id
属性。
现在,当对象模型准备就绪时,是时候决定资源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 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>
现在,在进入下一部分之前,让我们记下几个观察结果,这样你就不会错过它们。
method
代表一个POST方法。您也可以以全新的方式拥有更多属性或表单链接。所以我们的资源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}
子资源表示将与主要表示相同或为主要表示的子集。
Create不是幂等操作,在HTTP协议中 - POST
也不是幂等的。所以使用POST。
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。
请注意,在从系统中删除子资源时,应该对决定行为进行足够的分析。通常,您可能希望在这些请求中SOFT删除资源 - 换句话说,将其状态设置为INACTIVE。通过遵循此方法,您不需要从其他位置查找和删除其引用。
在实际应用程序中,您需要在设备上应用配置 - 或者您可能希望从设备中删除配置(而不是从主要集合中删除)。在这种情况下,您应使用PUT和DELETE方法,因为它具有幂等性质。
//Apply Configuration on a device
HTTP PUT /devices/{id}/configurations
//Remove Configuration on a device
HTTP DELETE /devices/{id}/configurations/{id}
到目前为止,我们只设计了对象模型,URI,然后决定了它们的HTTP方法或操作。您还需要处理应用程序的其他方面:
1)记录
2)安全性
3)发现等
在下一篇文章中,我们将在java中创建此应用程序以获得更详细的理解。
Powered by RESTful API 中文网 + with by 全栈开发网. 网站地图 按Ctrl+D试试 .