gpt4 book ai didi

http - 将一种资源附加到另一种资源的 RESTful 方式是什么?

转载 作者:可可西里 更新时间:2023-11-01 16:18:58 26 4
gpt4 key购买 nike

这是我在这个地方找不到相同问题的少数几个时刻之一,所以我试图描述我的问题并希望得到一些帮助和想法!

假设...

我想为域模型设计一个 RESTful API,它可能具有如下实体/资源:

class Product
{
String id;
String name;
Price price;
Set<Tag> tags;
}


class Price
{
String id;
String currency;
float amount;
}


class Tag
{
String id;
String name;
}

API 可能如下所示:

GET /products
GET /products/<product-id>
PUT /prices/<price-id>?currency=EUR&amount=12.34
PATCH /products/<product-id>?name=updateOnlyName

关于更新引用:

PATCH /products/<product-id>?price=<price-id>
PATCH /products/<product-id>?price=

可以将产品的价格引用设置为另一个现有价格,或删除该引用。

但是我如何才能将现有标签的新引用添加到产品中呢?

如果我想将该引用存储在关系数据库中,我需要一个用于该多对多关系的关系表“products_tags”,这为我们带来了一个清晰的解决方案:

POST /product_tags [product: <product-id>, tag: <tag-id>]

但是基于文档的 NoSQL 数据库(如 MongoDB)可以将其存储为每个产品的一对多关系,因此我不需要为必须创建的“新资源”建模以保存一种关系。

但是

POST /products/<product-id>/tags/ [name: ...]
creates a new Tag (in a Product),

PUT /products/<product-id>/tags/<tag-id>?name=
creates a new Tag with <tag-id> or replaces an existing
Tag with the same id (in a Product),

PATCH /products/<product-id>?tags=<tag-id>
sets the Tag-list and doesn't add a new Tag, and

PATCH /products/<product-id>/tags/<tag-id>?name=...
sets a certain attribute of a Tag.

所以我可能想说点什么链接:

ATTACH /products/<product-id>?tags=<tag-id>
ATTACH /products/<product-id>/tags?tag=<tag-id>

所以重点是:

我不想创建新资源,

我不想设置资源的属性,但是

我想将资源添加到另一个资源属性,这是一个集合。 ^^

因为一切都与资源有关,所以可以说:

我想将一个资源附加到另一个。

我的问题:哪种方法是正确的,URL 应该是什么样子?

最佳答案

您的 REST 是一个应用程序状态驱动程序,并非旨在反射(reflect)您的实体关系。

因此,在 REST 中没有“如果数据库中存在这种情况”。也就是说,您有非常好的 URI。

您谈论的是 ID。什么是标签?标签不是一个简单的字符串吗?为什么它有一个id?为什么它的 id 不是它的名称字符串?

为什么没有 PUT /products/<product-id>/tags/tag_name=

PUT 是幂等的,因此您基本上是在断言 product-id 引用的产品存在标签.如果你多次发送这个请求,你会得到 201 Created第一次和200 OK下一次。

如果您正在构建一个简单的系统,其中单个并发用户在单个 Web 服务器上运行且没有并发请求,您现在可能会停止阅读

如果中间有人删除了该标签,您的下一个放置请求将重新创建该标签。这是你想要的吗?

使用乐观并发控制,你每次都会传递文档的ETag a,并返回409 Conflict如果你在服务器上有较新的版本 b 和 diff,a..b不甘心。对于标签,您只是使用 PUT 和 DELETE 动词;这样您就不必比较/查看协调。

如果你正在构建一个中等高级的并发系统,具有先写者胜出的语义,在单个服务器上运行,你现在可以停止阅读了

也就是说,我认为您没有考虑过您的交易边界。你在修改什么?资源? ,您正在修改 product 的值对象资源;它的标签。那么,根据您的资源模型,您应该使用 PATCH .你关心并发吗?好吧,关于 PATCH,你还有更多的事情要考虑:

HTTP PATCH 的 RFC 是这样说的:

With PATCH, however, the enclosed entity contains a set ofinstructions describing how a resource currently residing on theorigin server should be modified to produce a new version. The PATCHmethod affects the resource identified by the Request-URI, and it alsoMAY have side effects on other resources; i.e., new resources may becreated, or existing ones modified, by the application of a PATCH.

PATCH is neither safe nor idempotent as defined by [RFC2616], Section9.1.

我现在可能会停止在您的脑海中加入奇怪的想法。如果您希望我继续沿着这条路走更长的时间,请发表评论;)。可以说还有更多的考虑可以做。

关于http - 将一种资源附加到另一种资源的 RESTful 方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10014161/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com