请记住,REST 就是在需要时对资源进行多种表示,因此首先要确定的事情之一是资源是什么以及它们之间是否存在任何关系。
在我看来,您似乎拥有将预算作为资源和将预算预览作为资源的概念,并且您还希望能够在以后检索它们中的任何一个。
我建议以下 URI 似乎
[GET]http://example.com/budgetPreviews/generate
这将在服务器上生成并返回一个budgetPreview,而不存储它。 IMO 在 API 中似乎不清楚创建budgetPreview 的路径是否嵌套在预算下。我还主张稍微远离“所有端点必须是名词”,以支持可以在资源上或使用资源执行的业务操作。如果有人争论,您可以将生成更改为“generateRequest”,因为实际上您正在将文档传递给服务器,其中填充了代表您的请求以生成预算预览的值。我在这里做出的一个假设是,服务器构建budgetPreview 所需的所有信息都是从客户端在GET 请求中传递的。
这里要注意的一件事是,您需要将所有信息作为查询参数包含在 URI 中,因为返回的值会因参数而异。在 GET 的主体中传递值,然后赋予该主体语义含义(即根据主体中的值创建不同的资源)将破坏缓存(如果您这样做的话)。
[GET]http://example.com/budgetPreviews
返回所有现有存储的budgetPreviews
[PUT]http://example.com/budgetPreviews/{GUID}
这里使用put创建资源并允许客户端确定id意味着存储资源的请求可以在超时的情况下重试,并允许幂等性。在存储预算预览的同时,您可以在参数中提供预算 ID 并将它们链接起来。
[GET] http://example.com/budgets/{GUID}/budgetPreview
[GET] http://example.com/budgetPreviews/{GUID}
这些是标识相同资源的不同 URI,并允许客户端以不同的方式使用budgetPreview
另外一点是不要混淆您的底层资源或实现细节,例如调用哪个方法与您面向公众的 API 的外观。旨在让您面向公众的 API 尽可能适合客户端,并且您返回的表示专注于对客户端合约进行建模,而不是底层资源的持久化。
另外,一位智者曾经告诉我的另一件事是,请记住您有无限的 URI 供您使用,所以当它为您的 API 提供清晰性和您的客户确切想要的内容时,不要害怕创建更多。