我目前正在设计一个API来处理来自移动客户端的请求。为了在后端和客户端之间实现某种程度的解耦,我想以RESTful方式定义Web服务。我面临的挑战是为一次调用返回多个具有不同类型的对象。
假设我们有以下型号:
据我了解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?
答案 0 :(得分:1)
正如@Tarken所提到的/boats
请求不应返回顶层的句子(因为网址假定您要求收集资源Boat
)
如果关系定义如下
Harbour:
boats: Boat[]
sheds: Shed[]
Shed:
boats: Boat[]
Boat:
harbour: Harbour
shed: Shed
/harbours/ID
然后返回Harbour
代表,并设置boats
和sheds
关系。
{
boats:
[
{ Boat },
{ Boat },
..
],
sheds:
[
{ Shed },
{ Shed },
..
],
...
}
这里没有什么是违反宁静原则的 - url唯一标识资源和资源表示可以是任何东西,也可以链接到其他资源。
答案 1 :(得分:0)
创建一个包含Harbour
和Boat 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
}
]
}
修改强>
由于您希望通过发送一个请求并排boats
和Sheds
,api/hourbours/{id}
根据REST API
设计原则看起来很不错。
在请求sheds
时获取所有boats
并不符合理想的REST API设计,但如果您希望实现相同目标,则可以执行以下操作。
如果你想这样,那么first one
/api//harbours/{id}/boats
对我来说很好。