设计 REST API

Designing a REST API

在我的申请中,我会有客户尝试预订一些时段。为此,客户端将提供一些输入,基于该输入,我必须首先创建这些插槽,然后 return 将它们提供给客户端。那么在拿到slots之后,用户会预定其中一个slots。此“预订”操作并未创建任何新资源,而只是修改了 2 个现有资源。

如何设计我的 URI 以及我应该使用什么方法?

编辑:

我有 1 个现有资源,其 URI 是:/api/v1/vehicle/id

用户将使用应用程序前端填写一些表单数据,字段为 datebooking-type 并提交。然后后端将使用此数据来“计算”(当前不存在名为 slots 的资源)用户可用的预订时段。这些计算出的 slots 然后将保存在数据库中并 returned 作为对用户的响应。在这些插槽中,用户将 book 个插槽。但是,此 book 操作不会创建任何新资源,而只会修改现有的 vehicle 资源(向其添加与预订相关的数据)和由前一个 return 编辑的插槽对象要求。我想为此创建一个 REST API。

我想这样做:

POST /api/v1/slot                    (1)
PUT/PATCH /api/v1/vehicle/id            (2)
PUT/PATCH /api/v1/slot/id            (3)

首先,我不确定是否应该在 (2) 和 (3) 中使用 PUTPATCH。我只会对请求提供部分更新。其次,当用户选择一个插槽并点击book按钮时,前端只能向服务器发送1个请求。但是在这里,我需要修改2个资源。我该怎么做呢?我想我应该创建 1 个像 /api/v1/createbooking 这样的 URI 并使用 POST 方法。然后在我的后端调用 2 种不同的方法来更新 vehicleslot 对象。这个URI结构和命名好不好?

How do I design my URIs and what methods should I use?

你会如何处理网页?

这听起来像是让用户导航到一个收集日期、预订类型等的表单。用户提交表单,并将信息发送到服务器;因为这本质上不是 read-only 操作,我们希望表单指示应该使用 POST 方法。

服务器将进行本地更改,并向用户显示一个新表单,其中输入控件显示可用选项。再一次,选择一个插槽似乎没有 read-only 语义(我们将信息传递给服务器),所以我们会再次看到 POST。

URI 目标是什么?选择哪些资源应处理 POST 请求的一种方法是考虑 cache invalidation 的含义;因为缓存知道要使成功的 POST 请求的 target-uri 无效,所以将请求成功时可能会更改的资源作为目标可能很有用。

我的猜测是,第一个 post 会转到提供插槽选择的资源(因为我们正在做的是为客户生成新的选择)。

对于第二次提交,由于车辆的表示将通过选择插槽进行更改,因此将 POST 请求发送到车辆 uri 是有意义的。

总的来说,想想你是如何从服务器读取(GET)变化的信息的;您可以通过向同一 URI 发送一些请求来更改该信息。


I am not sure if I should use PUT or PATCH here

PUT 和 PATCH 通常可以一起使用,而不是作为不同的东西使用。它们是发送资源替换表示的两种不同方法。

一个简单的例子:如果您想更改 /home.html 的标题,您可以将整个 HTML 文档放入新标题,或者您可以修补 HTML通过以服务器理解的某种格式发送 patch-document 来记录文档。

换句话说,这两种方法都具有远程创作语义;我们通常会根据与您的域模型无关的考虑在它们之间进行选择(如果文档相对于 HTTP headers 的大小较小,客户端通常会选择 PUT 以获得额外的幂等语义保证。如果文档是真的很大,但变化很小,我们可能更喜欢PATCH)。


I need to modify 2 resources.

没有规定一个请求只能修改一个资源。更改的副作用可能会影响多个资源的表示(请参阅 RFC 7231 的 4.3.3 and 4.3.4)。

棘手的是告诉通用客户端(和中间组件)哪些缓存表示因更改而失效。开箱即用,我们只有有效请求 uri、位置和 Content-Location 的语义。位置和 Content-Location 已经意味着什么,所以你不能在没有引入大混乱的情况下劫持它们)。

您可以使用 Linked Cache Invalidation 来做到这一点,使用“众所周知的”link 关系来识别已被请求更改的其他文档。不幸的是,LCI似乎还没有达到“标准”的地位,所以我们可能暂时不走运。