我希望在现有项目之上公开一些域RESTful API。我需要建模的实体之一有一个文档:设置。设置是使用应用程序创建的,是一个单例文档。我想通过精心设计的基于资源的RESTful API来公开它。
通常在为具有多个项目的资源建模API时,其类似于:
GET /employees/ <-- returns [] of 1-* items
GET /employees/{id}/ <-- returns 1 item
POST /employees/ <-- creates an item
PUT /employees/{id}/ <-- updates all fields on specific item
PATCH /employees/{id}/ <-- updates a subset of fields specified on an item
DELETE /employees/{id}/ <-- deletes a specific item
选项1:如果我以相同的方式建模设置,则构建以下API:
GET /settings/ <-- returns [] of 1-* items
[{ "id": "06e24c15-f7e6-418e-9077-7e86d14981e3", "property": "value" }]
GET /settings/{id}/ <-- returns 1 item
{ "id": "06e24c15-f7e6-418e-9077-7e86d14981e3", "property": "value" }
PUT /settings/{id}/
PATCH /settings/{id}/
这对我来说有一些细微差别:
选项2:我的思绪朝这个方向发展:
GET /settings/ <-- returns 1 item
{ "id": "06e24c15-f7e6-418e-9077-7e86d14981e3", "property": "value" }
PUT /settings/
PATCH /settings/
此设计消除了下面提到的细微差别,并且不需要ID到PUT或PATCH。这对我来说是最一致的,因为所有请求都具有相同的形状。
选项3:另一种选择是将id添加回PUT和PATCH以要求它进行更新,但是API用户必须执行GET才能获得单身的id:
GET /settings/ <-- returns 1 item
{ "id": "06e24c15-f7e6-418e-9077-7e86d14981e3", "property": "value" }
PUT /settings/{id}/
PATCH /settings/{id}/
这似乎不一致,因为GET 1与UPDATE 1请求的形状不同。它也不需要消费者执行GET来查找单例的标识符。
答案 0 :(得分:5)
Resource
的ID是Url
本身,不一定是Guid
或UUID
。 Url
应该唯一 ID 包含Resource
,在您的情况下为Settings
实体。
但是,为了成为RESTfull,您必须在索引Url(即/
路径)中使用适当的rel
属性指向此资源,这样客户端就不会对Url进行硬编码,例如:
GET /
{ ....
"links": [
{ "url" : "/settings", "rel" : "settings" }
], ...
}
除了Url
之外,没有任何细节可以访问单个资源,不包含Guid,Uuid或任何其他数值。
答案 1 :(得分:2)
据我所知,选项2完全是RESTful。
RESTful API背后的核心理念是您正在操纵“资源”。 “资源”一词有意留下含糊不清的内容,以便它可以引用对特定应用程序很重要的内容,以便API可以只关注 如何访问内容,而不管是什么将访问内容。
如果您的资源是单身,则将ID值归属于它是没有意义的。 ID非常有用,并且通常在RESTful API中使用,但它们不是使REST RESTful的核心部分,并且正如您所注意到的,实际上会使访问单例资源更加麻烦。
因此,您应该取消ID并同时使用
GET /settings/
和
GET /settings/{id}
始终返回设置单例对象。 (不需要access-by-id,但是如果有人尝试的话,这很好)。此外,请务必记录您的API端点,以便消费者不要指望数组:)
回复:你的问题,
我认为选项2是建模的首选方式,我相信要求你的消费者为id做一个GET实际上有点反模式。
答案 2 :(得分:2)
我认为这里的混淆是因为设置这个词是复数,但资源是单身。
为什么不将资源重命名为/configuration
并使用选项2?
对于API的消费者而言,这可能不那么令人惊讶了。
答案 3 :(得分:2)
你可能正在思考它。 HTTP或REST中没有单例的概念。
GET /settings/
完全没问题。
顺便说一下,我们很难将其与DDD联系起来 - 至少如果你没有提供关于设置在你的域中的含义的更多背景信息,那么至少不会这样做。
如果不合适,您可能还想尝试在设置上添加“带ID的实体”方法。并非系统中的所有对象都是实体。