假设有一个事件托管服务。主持人可以使用以下方式登录并创建事件:
POST /events
创建事件
GET /events
获取主机创建的所有事件
GET /events/1
获取ID为1的事件(如果由主机创建,否则返回错误)
现在,主持人希望为客人可以在其上进行RSVP的事件生成批量邀请代码,主持人应该能够看到响应。主机只能与来宾共享代码,并且不希望共享事件ID(因为它看起来很酷)
POST /events/1/invites
,其中包含受邀者列表以生成代码
GET /event/1/invites
获取被邀请者列表并查看他们的回复
GET /event/1/invites/SECRET007
获取特定邀请的回复
到目前为止看起来不错,但是邀请RSVP的惯例是什么?
一个选项是:PUT /invites/SECRET007
,但是问题在于它与GET对应项不匹配。
另一种选择是保留PUT API并更改所有其他邀请API
POST /invites
正文:{event:1 ...},其中包含被邀请者列表以生成代码
GET /invites?event=1
获取被邀请者列表并查看他们的回复
GET /invites/SECRET007
获得邀请
但是在这种情况下,GET /invites
毫无意义,必须始终使用事件ID来调用它。
这里遵循的正确约定是什么?
编辑:这里的重要要求是主机只能与来宾共享邀请,并且来宾应该只能使用该ID进行RSVP。
答案 0 :(得分:2)
关于可能有所帮助的事情:REST并不真正理解您在此描述的“子资源”。
/invites
/invites?event=1
/invites/SECRET007
就REST而言,它们是三个完全独立的标识符,因此是三个完全独立的资源。资源标识符的拼写没有传达任何语义上的意义。这里的关系等效于这些:
/4498232d-9bf9-4405-a94d-ed5d2cfc5551
/951139d9-d5a9-43fb-ab23-ba4b383a7a11
/6b2d8b31-981d-4128-b354-776b8375decd
您使用的路由库可能会观察到标识符路径中的相似之处,并对这些信息进行一些有趣的操作,但这是在“统一接口”之后进行的实现选择。 >
例如:
DELETE /invites
如果该请求成功,则符合REST的缓存仍将保存/invites?event=1
和/invites/SECRET007
的副本。标识符的层次结构没有任何意义。
这反过来意味着(a)您可以按自己喜欢的方式安排资源,并且(b)您可以选择任何方便的拼写方式。
具有许多“关于”同一事物的资源是正常,每个资源都有其自己的标识符。比较
https://stackoverflow.com/questions/57640910/rest-api-convention-for-subresource
https://api.stackexchange.com/2.2/questions/57640910?order=desc&sort=activity&site=stackoverflow
因此,如果您要拼写一个人类可以理解的资源标识符,那么您需要仔细考虑您的资源模型以及要提供给客户的赠品的集合。
答案 1 :(得分:1)
我不知道这是否是“正确的约定”,但是当我遇到类似的情况时,我采取了务实的方法,并试图避免深层的资源嵌套,除非绝对必要。
我确定“绝对必要”是指子资源标识符不是全局唯一的。例如。如果您的路径是:
/events/1/invites/1
/events/1/invites/2
/events/2/invites/1
然后,邀请ID本身不足以标识确切的邀请,您需要一个包含事件ID的复合ID。
如果邀请ID 是全局唯一的-不仅是事件唯一的-那么就没有理由不能拥有根/invites
资源。
/events:
get:
description: list events
post:
description: create event
/{id}:
get:
description: get event with id {id}
/invites:
get:
description: list all invites for an event
post:
description: create an invite for an event
/invites:
/{id}:
get:
description: get invite with id {id}
put:
description: update invite with id {id} (record RSVP)
如果您认为这是必需的,则实际上可以有重复的路由来访问相同的资源。例如。您可能有/events/{eventId}/invites/{inviteId}
和/invites/{inviteId}
访问同一邀请。如果您通过活动发现邀请,则一条路线很有意义,第二条路线是直接链接到已知邀请的快捷方式。
只是我对此事的想法:)
答案 2 :(得分:0)
Microsoft在设置REST API时发布了包含指导的复杂文档。每个用例都没有详尽的规则,因此您必须做出自己的决定。似乎更喜欢使用GET / POST / PUT /events
之类的CRUD模式。