以RESTful方式返回具有多种类型的对象

时间:2014-02-11 13:48:36

标签: rest mobile

我目前正在设计一个API来处理来自移动客户端的请求。为了在后端和客户端之间实现某种程度的解耦,我想以RESTful方式定义Web服务。我面临的挑战是为一次调用返回多个具有不同类型的对象。

假设我们有以下型号:

  • Harbour ...顶级条目
  • 船棚 ...分配到特定港口(0..n)
  • ...分配到特定的船棚(0..n),或直接到港口(0..n)

据我了解REST,如果我现在想要显示港口的所有船只和棚屋,我会发出两个请求:

/harbours/{harbour_id}/boats返回所有船只的清单。棚屋里的小船将包含一个连接到他们所在棚屋的id。

/harbours/{harbour_id}/sheds返回所有棚屋的清单

由于我想在移动方案中使用Web服务,因此将这两个调用合并为一个是理想的。然后,这可以返回嵌套在其中的棚子对象的船只列表,或者两个对象类型并排:

/harbours/22/boats

[
   {
      "id":1,
      "boatName":"Mary",
      "boatShed":{
         "id":1,
         "shedName":"Dock 1",
         "capacity":55
      }
   },
   {
      "id":2,
      "boatName":"Jane",
      "boatShed":{
         "id":1,
         "shedName":"Dock 1",
         "capacity":55
      }
   }
]

/harbours/22/boats

{
   "boats":[
      {
         "id":1,
         "boatName":"Mary",
         "boatShedId":1
      },
      {
         "id":2,
         "boatName":"Jane",
         "boatShedId":1
      }
   ],
   "sheds":[
      {
         "id":1,
         "shedName":"Dock 1",
         "capacity":55
      }
   ]
}

我现在的问题是,哪些方法更接近REST背后的想法,还是根本不是RESTful?

2 个答案:

答案 0 :(得分:1)

正如@Tarken所提到的/boats请求不应返回顶层的句子(因为网址假定您要求收集资源Boat

如果关系定义如下

Harbour:
    boats: Boat[]
    sheds: Shed[]

Shed:
    boats: Boat[]

Boat:
    harbour: Harbour
    shed: Shed

/harbours/ID然后返回Harbour代表,并设置boatssheds关系。

{
  boats: 
  [
    { Boat },
    { Boat },
    ..
  ],
  sheds: 
  [
    { Shed },
    { Shed },
    ..
  ],
  ...
}

这里没有什么是违反宁静原则的 - url唯一标识资源和资源表示可以是任何东西,也可以链接到其他资源。

答案 1 :(得分:0)

创建一个包含HarbourBoat Shed信息的Boat模型。如果我在Java中实现该服务,那么我会做这样的事情:

class Boat{
...
}

class BoatShed{
...
}

class Harbour{
List<Boat> boats;
List<BoatShed> boatSheds;
...
}

您可以创建像/api/harbours/{harbourId}这样的API。

根据您的问题,您希望在harbour中显示所有船只和棚屋,比如id=1234,您可以提出这样的请求:

GET /api/harbours/1234

这将返回Boats列表和Boat Sheds列表,如下所示:

{
"boats":[
  {
     "id":1,
     "boatName":"Mary",
     "boatShedId":1
  },
  {
     "id":2,
     "boatName":"Mary2",
     "boatShedId":2
  }
],
"sheds":[
  {
     "id":1,
     "shedName":"Dock 1",
     "capacity":55
  },
  {
     "id":2,
     "shedName":"Dock 2",
     "capacity":50
  }
  ]
}

修改 由于您希望通过发送一个请求并排boatsShedsapi/hourbours/{id}根据REST API设计原则看起来很不错。

在请求sheds时获取所有boats并不符合理想的REST API设计,但如果您希望实现相同目标,则可以执行以下操作。

如果你想这样,那么first one /api//harbours/{id}/boats对我来说很好。