1

我正在经历描述为一个好的 REST API的例子。GET 是在基本 URI 上发送的,并且带有客户端已经知道的媒体类型(这很好,根据 REST 原则)。

 To server:

 GET /
 Host: xrgy.cloud.sun.com
 Authorization: Basic xxxxxxxxxxxxxxxxxxx
 Accept: application/vnd.com.sun.cloud.Cloud+json
 X-Compute-Client-Specification-Version: 0.1

 From Server:

 HTTP/1.1 200 OK
 Content-Type: application/vnd.com.sun.cloud.Cloud+json
 Content-Length: nnn

 {
   "implementation_version": "597",
   "vdcs": [
     {
       "name": "XRGY Virtual Data Center",
       "uri": "/vdc"
     }
     {
       "name": "R&D sandbox"
       "uri": "/sandbox"
     }
   ],
   "uri": "http://xrgy.cloud.sun.com/",
   "specification_version": [
     "0.5"
   ]
 }

但我陷入困境的是客户端如何为后续请求设置媒体类型。我知道客户端从上一个响应中获得了下一个请求的 URI。但是它是从哪里获得媒体类型的呢?如果它是客户端的先验知识,那么客户端通常如何维护这样的 URI:media-type 映射?看来我肯定在这里错过了一些基本知识。以下是使用媒体类型发送的后续请求:application/vnd.com.sun.cloud.Vdc+json!

To server:

 GET /vdc
 Host: xrgy.cloud.sun.com
 Authorization: Basic xxxxxxxxxxxxxxxxxxx
 Accept: application/vnd.com.sun.cloud.Vdc+json
 X-Compute-Client-Specification-Version: 0.1

From server:

 HTTP/1.1 200 OK
 Content-Type: application/vnd.com.sun.cloud.Vdc+json
 Content-Length: nnn

 { 
   "name" : "XRGY Virtual Data Center",
   "uri" : "http://xrgy.cloud.sun.com/vdc",
   "vm_templates" : "http://cloud.sun.com/resources/template-cat.json",
   "addresses" : [
     {
       "name": "144.34.100.199",
       "uri": "/addresses/144.34.100.199",
       "ip_address": "144.34.100.199"
     }
   ],
   "cluster" : {
     "name" : "ROOT",
     "uri" : "/vdc/",
     "tags" : [ ],
     "volumes" : [ ],
     "clusters" :  [
     ]
     "tags" : [ ],
     "controllers" : [
       "start" : "/vdc/ops/start",
       "stop" : "/vdc/ops/stop",
     ]
     "vnets" : [
       {
         "name": "vnet1",
         "uri": "/vnets/10.31.145.0",
         "netmask": "255.255.255.0",
         "network": "10.31.145.0"
       }
     ],
     "vms": [
       {
        * SNIPPED *
       }
     ]
   }
 }

我已经看到其他示例,其中媒体类型也是响应中链接的一部分,例如以下响应,我可以理解。

201 Created
Content-Type: application/vnd.bank.org.transfer+xml;charset=UTF-8

<transfer xmlns="urn:org:bank:accounts">
    <link rel="self"
          href="http://bank.org/transfer/XTA8763"/>
    <link rel="http://bank.org/rel/transfer/from"
          type="application/vnd.bank.org.account+xml"
          href="http://bank.org/account/AZA12093"/>
    <link rel="http://bank.org/rel/transfer/to"
          type="application/vnd.bank.org.account+xml"
          href="http://bank.org/account/ADK31242"/>
    <link rel="http://bank.org/rel/transfer/status"
          type="application/vnd.bank.org.status+xml"
          href="http://bank.org/check/XTA8763"/>
    <id>transfer:XTA8763</id>
    <amount currency="USD">100</amount>
    <note>RESTing</note>
</transfer>
4

2 回答 2

3

简单地说,是的,客户需要对所涉及的媒体类型有一些先验知识。因为客户端实际上设置了它可以使用的媒体类型。由于客户端只理解“某些”媒体类型,如果它发送一个应用程序不支持的媒体类型的请求,那么客户端就很不走运了。

因为,在现实世界中,我们尽量不让客户端盲目调用返回他们不理解的有效载荷的服务,所以客户端将对所涉及的有效载荷有一些先见之明,尤其是非常具体的类型(相对于纯文本或应用程序/xml)。

最后,请记住,媒体类型将有效地告诉您有效负载的语法,但不会告诉您如何解释有效负载。您的客户也必须预先了解这些语义,因此对媒体类型有初步了解的负担实际上并不是参与的特别障碍,这只是生活中的事实。

于 2013-04-03T21:19:22.597 回答
1

客户端负责告诉服务器他们理解/喜欢什么样的响应。这就是 Accept 标头所指示的。服务器以试图满足客户端请求的内容进行响应。Content-Type 标头指示实际返回的内容。理想情况下,此标头的值与 Accept 标头的值相同。

请参阅RFC 2616中的第 14.1 和 14.17 节。

在您的示例中,客户端作者可能正在向客户端注入知识,这并不是真正的 100% RESTful 客户端。

于 2013-04-03T20:39:25.133 回答