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
3pResponse 是 marketplaces、customers、 的子资源合同和计划。
使用这种方法可能会想到还有一个资源 /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".
在开发 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
3pResponse 是 marketplaces、customers、 的子资源合同和计划。
使用这种方法可能会想到还有一个资源 /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".