#discussRESTful API设计问题
– 照片由Omer Rana在Unsplash上
最近在真正的生产系统上工作时,我问自己一个问题:
REST API是否应受当前架构选择的约束?
为了说明这个问题,我发明了一个例子。
让我们想象一下用于租车的系统。该业务类似于Airbnb的“汽车租赁”。租车的小公司可以在系统中注册他们的位置,以接触更广泛的潜在客户。该系统允许他们管理他们的汽车,但不允许任何其他租赁现场汽车。
让我们想象一下,我们是一个创业公司,并建立了系统。我们从小规模开始,使用关系数据库将所有汽车存储在一个表中。每张车都由此表中的唯一ID标识。
我们想为我们的系统导出RESTful API。
除此之外,我们需要API来浏览一个地方的所有汽车并获得单车细节。
用于列出现场所有汽车的API可能如下所示:
GET /spots/{spotId}/cars
它将返回一个汽车列表,我们可以从中获取汽车的ID。
通过ID获取汽车的API可能如下所示:
GET /spots/{spotId}/cars/{carId}
要么
GET /cars/{carId}
由于我们希望与API设计的良好实践保持一致,我们决定采用更长的路径,因为汽车是不能单独存在且始终属于给定地点的资源。路径 /spots/{spotId}/cars
清楚地解释了这种关系
然而 spotId
在路径上是多余的。
因为我们把所有车都放在单人桌上,而且我们知道车的ID,因为我们从车上拿到了车 /spots/{spotId}/cars
端点,我们真正需要的唯一变量是 carId
。
当然,在我们的关系数据库中,我们将有从汽车到现场的关系,我们可以添加 spotId
在查询中,但并不重要。
例如。我们可以有一个像这样的查询:
select c.* from cars c inner join spots s on s.id = c.spot_id where s.id = :spotId and c.id = :carId
但它会得到与以下相同的结果:
select * from cars where id = :carId
所以,我们应该使用 /spots/{spotId}/cars/{carId}
要么 /cars/{carId}
作为端点路径?
我一直在考虑它,两种选择都有利弊。如前所述,从API透视图的语义来看,较长的一个听起来更合适,但较短的一个在后端架构的当前状态下更容易使用和实现。
如果我们考虑我们服务的发展,那么我们可以想象我们可能想要将汽车表分成每个单独的点。如果数据量增加,或者我们想要分配数据库并在每个点附近的位置设置多个实例(以获得更好的性能和扩展),则可能会发生这种情况。然后,每辆车都是唯一的但在单个数据库实例中(或者如果我们考虑给定地点的特定位置的实例集群)。然后我们只能通过一对来区分汽车 spotId
和 carId
更长的API路径会更有意义。
最后,我回答说:
API还没有。当架构发展时,API也是如此。
目前有意义且简单(/cars/{id}
)将来可能不再适用。将来,如果我需要将汽车存储分成每个汽车租赁点的单独表/数据库,新API可能如下所示: /spots/{spotId}/cars/{carId}
。另一方面,这可能永远不会发生,正如唐纳德克努特曾经说过的那样“过早优化是所有邪恶的根源”。
你对这个问题的答案是什么?如果您有更多想法,请在评论中与我和其他读者分享。