REST URI 设计

REST URI design

在开发 RESTFul 网络服务时,我对请求实体的建模感到困惑。如果处理请求所需的所有数据都是实体的一部分,还是我应该将一些数据移动到 URL 路径(假设我在这些数据之间具有逻辑层次结构)。

例如:

路径

/api/payment/3pResponse

实体架构

{
  "marketplacedId" : String,
  "customerId: String,
  "contractId: String,
  "planId": String,
  "3pResonse" : {},
  "3pResponseURI" : "string" 
}

对比

路径

/api/payment/marketplaces/{mktId}/customers/{customerId}/contracts/{contractId}/plans/{plandId}/3pResponse

实体架构

{
  "3pResonse" : {},
  "3pResponseURI" : "string" 
}

请注意,/api/payment/marketplaces/{mktId} 等路径上的资源可能并不真正存在于我的应用程序中。

两者在技术上都可行,但我想了解在此类场景中围绕实体建模的最佳实践。

当您设计 REST API 时,您将功能需求映射到类似于面向对象设计方法的资源。

资源是一个像对象一样的通用概念。 资源有两个基本属性,它是可识别的,并且有一个或多个可从外部访问的表示。

在您的第一个示例 /api/payment/3pResponse 中,您只有一个 3PResponse 资源,您可以使用 PUT 方法完全更新它。

当您尝试访问它们时,您可能会通过矩阵参数识别资源。 (这只是一种方法,还有其他方法)

/api/payment/3pResponse;marketPlace=x;customerId=y;contractId=z;planId=k

在你的第二种方法中

/api/payment/marketplaces/{mktId}/customers/{customerId}/contracts/{contractId}/plans/{plandId}/3pResponse

3pResponsemarketplacescustomers 的子资源合同计划

使用这种方法可能会想到还有一个资源 /api/payment/marketplaces/,其中 return 是一个市场列表 或者有一个资源 /api/payment/marketplaces/{mktId}/customers/{customerId}/contracts/{contractId} 其中 return 是客户的合同。

您的应用程序应该 return 这些资源的有用结果,即使客户端不应尝试解释您的 uri。

Stefan Tilkov 关于 REST API 设计 REST: I don't Think it Means What You Think it Does

的精彩介绍

比 URI 和资源的实际设计更重要的是保持 URI 稳定。

引自Tim Berners-Lee:"Cool URIs don't change".