REST HATEOAS:如何在浏览链接时确定和设置媒体类型?

时间:2013-04-03 20:20:23

标签: json http rest mime-types hateoas

我经历的what被描述为good 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:媒体类型映射? 看来我肯定错过了一些基本知识。 以下是使用媒体类型发送的后续请求: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>

2 个答案:

答案 0 :(得分:3)

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

因为在现实世界中,我们试图不让客户盲目调用返回他们不理解的有效负载的服务,客户端将对所涉及的有效负载有一些预知,特别是非常特定的类型(vs plain) / text或application / xml)。

最后,回想一下,媒体类型将有效地告诉您有效载荷的SYNTAX,而不是如何解释有效载荷。你的客户也必须预先知道这些语义,所以初步了解媒体类型的负担实际上并不是参与的障碍,这只是生活中的一个事实。

答案 1 :(得分:1)

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

RFC 2616中的第14.1和14.17节。

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