背景
我正在构建一个允许客户端操作地理空间对象的 API。这些对象包含世界上的位置(纬度/经度)和大量元数据。实际的 API 相当大,所以我在这里提供一个简化版本。
当前 API
考虑一个具有两个对象、特性和属性的 API。
功能端点是/api/feature
并且看起来像:
{
id: 5,
name: "My super cool feature",
geometry: {
type: "Point",
coordinates: [
-88.043355345726,
43.293055846667315
]
}
}
属性端点是/api/attribute
。一个属性看起来像:
{
id: 3,
feature_id: 5,
name: "attr-name",
value: "value"
}
您可以通过使用不同的 HTTP 方法向其端点发出 HTTP 请求来与这些对象进行交互,就像您可能期望的那样:
GET /api/feature/5
读取 id 为 5 的特征。PUT /api/feature/5
更新 id 为 5 的功能。POST /api/feature
创建一个新功能。DELETE /api/feature/5
删除 id 为 5 的特征。
属性也是如此。
属性通过外键与特征相关联(通常表示为“特征有很多属性”)。
问题
能够制作要素及其所有元数据(属于它的所有属性)的副本会很有用。用例或多或少是,“我刚刚制作了这个功能并给了它一堆属性,现在我想要同样的东西......但是在那里。” 因此,这两个特征之间的唯一区别是它们的几何形状。
解决方案#1:让客户去做。
我的第一个想法是让客户去做。在新位置创建具有相同名称的新要素,然后遍历源要素上的所有属性,发出POST
请求以在新要素上复制它们。然而,这存在一些问题。首先,它不是原子的。如果在此过程中客户端的 Internet 连接中断,您将得到一个不完整的副本,这是蹩脚的。其次,它可能会很慢,尤其是对于具有许多属性的功能。无论如何,这是一个坏主意。
解决方案 #2:向 API 添加复制功能。
在单个 API 调用中执行复制服务器端将是更好的方法。这导致我https://www.rfc-editor.org/rfc/rfc2518#section-8.8和COPY
方法。能够在单个COPY /api/feature/5
请求中对功能进行深度复制似乎很理想。
问题
我的问题,在这里,是COPY
不太适合我设想的用途的语义。对资源发出COPY
请求会将该资源的副本执行到Destination
标头中指定的目标。根据 RFC,Destination
必须存在,并且它必须是一个 URI,指定复制的资源将在哪里结束。在我的例子中,复制特征的目的地是一个几何图形,它绝对不是一个 URI。
所以,我的问题是:将几何图形的 json 填充到请求的Destination
标头中COPY
会是对规范的歪曲吗?COPY
在这里使用正确的东西吗?如果没有,有什么替代方案?我只是想确保我以最符合 HTTP-kosher 的方式实现这一点。