具有多个必需参数的 RESTful URI 的最佳设计是什么?



我想看看是否有更多经验丰富的web服务老手能够在我需要强制性参数的地方评论设计RESTful URI的最佳方式。举个例子,我想设计一个请求数据的URI:

example.com/request/distribution

然而,根据我的理解,这种方法是,如果应用更具体的URI关键字,应该在更高的级别返回更多的数据,而会返回更详细的数据,但在我的情况下,我至少需要3个值才能实现这一点。这3个值将是日期值、帐户值和专有分发代码值。例如:

example.com/request/distribution?acct=123&date=20030102&distcode=1A;1B;1C

这被认为是一个"RESTful"URL,还是有更好的方法更有意义?任何意见都将不胜感激。

顺便说一句,Python是首选语言。谢谢

URI根据定义不能是"unRESTful"的,因为URI规范是由REST体系结构风格指导的。如何使用URI可能会违反REST样式:

  1. 不遵循"客户端-服务器"约束;例如,通过使用WebSockets来实现服务器推送
  2. 不遵循"资源识别"约束;例如,使用URI的一部分来指定控制数据或资源元数据,而不是拘泥于识别资源,或者通过URI以外的某种机制(如会话状态或其他带外机制)来识别资源
  3. 不遵循"通过表示操纵资源"的约束;例如通过使用URI的查询字符串部分来传输状态
  4. 不遵循"自我描述消息"约束;例如,使用HTTPGET修改状态,或者传输ContentType为"text/html"的JSON
  5. 不遵循"超媒体作为应用程序状态引擎"的约束;例如,不提供要遵循的用户代理超链接,而是假设它将使用带外知识来构建超链接
  6. 不遵循"分层系统"约束,要求客户端了解服务器如何工作的内部细节(尤其是要求客户端在请求中提供这些细节)

以上都不一定是错误的选择。它们可能是系统的最佳选择,因为它们促进了某些体系结构特性(如效率或安全性)。它们不是REST风格的一部分。

您的资源由多个强制段标识,这是URI设计的一部分。正如Anton所指出的,example.com/request/distribution?acct=123&date=20030102&distcode=1A;1B;1Cexample.com/accounts/123/distributions/20030102/1A;1B;1C之间的选择纯粹是数据设计的问题,而不是URI层本身的问题。例如,对前者的PUT、POST或DELETE请求进行响应并没有错。如果客户端未能遵循任一链接,则会被视为已断开。一个系统期望其中一个通过超媒体响应以外的某种方式对客户端可用,这将被视为"unRESTful"。

最好先从资源而不是URI的角度创建RESTful API。它更多地与你的数据设计有关,而不是与你选择的语言有关。

例如,您有一个分发资源。您希望在基于web的API中表示它,因此它需要具有适当的唯一资源标识符(URI)。它应该是简单的,可读的,并且不太可能改变。这将是一个不错的例子:

http://example.com/api/distribution/<some_unique_id>

在将更多内容和层次结构放入URI之前,请三思而后行

您不希望随着数据模型或身份验证方案的发展而更改URI。更改URI对于您和使用API的开发人员来说是不酷和痛苦的。因此,如果您需要将身份验证传递到后端,您可能应该使用GET参数或HTTP头(例如,AWS S3 API允许两者)。

在GET参数(例如http://example.com/api/distribution/?id=<some_unique_id>)中投入太多似乎不是一个好主意,但IMO实际上并不重要[0]——只要您保持API文档的可访问性和最新性。

[0]更新:至少对于只读API。对于CRUD API,正如@daniel所指出的,当您拥有像上面第一个例子中那样的端点时,它会更方便。这样,您就可以很好地使用HTTP方法,为/api/distribution/<id>上的单个资源启用GET、PUT、DELETE,并为/api/distribution启用POST以创建新的分发版。

在研究答案时,发现了一个关于RESTful API的不错的演示:设计HTTP接口和RESTful Web服务

RESTful方法是将数据表示为资源,而不是请求的参数:

example.com/distribution/123/20030102/1A;1B;1C

当你考虑RESTful时,大多数时候你也应该考虑CRUD。

example.com/request/distribution?acct=123&date=20030102&distcode=1A;1B;1C

GET请求可以显示一些内容(CRUD中的R)。

但是您认为CUD部件的URL是什么?

最新更新