HTTP:使用COPY方法可以接受,其中Destination标头不是URI吗?

时间:2012-07-26 02:18:48

标签: api http copy rfc

背景

我正在构建一个允许客户端操作地理空间对象的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请求以在新功能上创建它们的副本。然而,这会遇到一些问题。首先,它不是原子的。如果客户端的互联网连接在这个过程中崩溃,你将留下一个不完整的副本,这是蹩脚的。其次,它可能很慢,特别是对于具有许多属性的功能。无论如何,这是一个坏主意。

解决方案#2:向API添加复制功能。

在单个API调用中执行复制服务器端将是更好的方法。这导致我http://tools.ietf.org/html/rfc2518#section-8.8COPY方法。能够在单个COPY /api/feature/5请求中对功能进行深层复制似乎是理想的。

问题

我的问题在这里,COPY的语义不太适合我设想的用途。在资源上发出COPY请求会将该资源的副本执行到Destination标头中指定的目标。根据RFC,Destination必须存在,并且它必须是指定复制资源最终位置的URI。在我的例子中,复制特征的目的地是几何,绝对不是URI。

所以,我的问题是:将几何体的json填充到Destination请求的COPY标题中是否会违反规范? COPY是否正确使用,在这里?如果没有,有什么替代品?我只是想确保我以最多的HTTP-kosher方式实现这一点。

1 个答案:

答案 0 :(得分:2)

那么,你需要一种方法来使目的地成为一个URI然后(为什么这是一个问题)。如果您正在使用“目标”标题字段来表示其他内容,则表示您未按规范使用COPY。 (而且,BTW,目前的规范是RFC 4918)