Web services 用于数据处理和方法链接的RESTAPI

Web services 用于数据处理和方法链接的RESTAPI,web-services,rest,restful-architecture,Web Services,Rest,Restful Architecture,如果问题质量不好,我提前道歉。我仍在开始学习RESTAPI的概念。我正在尝试为数据处理实现一个可伸缩的RESTAPI。以下是我目前能想到的 考虑一些可以使用GET调用检索的数字数据: GET http://my.api/data/123/ 用户可以应用一系列算术运算,如add和multiply。一种非宁静的方式是: GET http://my.api/data/123?add=10&multiply=5 假设: 数据库中的原始数据不变。只有经过修改的版本才会返回给用户 数据的大小很

如果问题质量不好,我提前道歉。我仍在开始学习RESTAPI的概念。我正在尝试为数据处理实现一个可伸缩的RESTAPI。以下是我目前能想到的

考虑一些可以使用
GET
调用检索的数字数据:

GET http://my.api/data/123/
用户可以应用一系列算术运算,如
add
multiply
。一种非宁静的方式是:

GET http://my.api/data/123?add=10&multiply=5
假设:

  • 数据库中的原始数据不变。只有经过修改的版本才会返回给用户
  • 数据的大小很大(比如说一个大的多维数组),因此我们无法在每次操作调用时返回整个数据。相反,我们希望将操作作为批处理应用,并最终返回最终修改的数据
我目前有两种休息方式:

1.将算术运算建模为数据的子资源。

如果考虑代码>添加< /代码>和<代码>乘以< /代码>作为数据的子资源。在这种情况下,我们可以使用:

GET http://my.api/data/123/add/10/
这将是安全且幂等的,因为原始数据从未更改。但是,我们需要将多个操作链接起来。我们能做到吗

GET http://my.api/data/123/add/10/multiply/5/
其中,
multiply
正在创建一个子资源
add/10/
,它本身就是
data/123的子资源

优点:

  • 无状态:服务器不保留任何关于修改数据的信息
  • 轻松访问修改后的数据:这只是一个简单的GET调用
缺点:

  • 链接:我不知道它是否容易实现
  • 长URI:随着每个操作的应用,URI变得越来越长
2.创建可编辑的数据对象: 在这种情况下,用户将创建原始数据的可编辑版本:

POST http://my.api/data/123/
会回来的

201 Created
Location: http://my.api/data/123/edit/{uniqueid}
然后,用户可以
修补该可编辑数据

PATCH http://my.api/data/123/edit/{uniqueid}
{add:10, multiply:5}
最后,
获取编辑后的数据

GET http://my.api/data/123/edit/{uniqueid}
GET http://my.api/data/123/edit/{uniqueid}
GET http://my.api/data/{uniqueid}
优点:

  • 清除URI
缺点:

  • 服务器必须保存已编辑数据的状态
  • 编辑不再是幂等的
  • 获取编辑的数据要求用户至少拨打3次电话
是否有一种更干净、更具语义的方式来实现RESTful数据处理

编辑: 如果你想知道这背后的真实问题是什么,我正在处理数字信号处理

作为一个简单的例子,您可以考虑对图像应用视觉过滤器。接下来,RESTful web服务可以执行以下操作:

GET http://my.api/image/123/blur/5px/rotate/90deg/?size=small&format=png

在你的问题中有几点值得回顾

基于REST的API是基于资源的

因此,请看第一个示例,尝试将转换属性链接到资源标识符后面的URL路径中

GEThttp://my.api/data/123/add/10/multiply/5/

…不太适合(正如您已经猜到的,动态实现非常复杂)

无国籍状态

REST中的无状态概念是围绕一个HTTP调用构建的,该调用包含足够的信息来处理请求并提供结果,而无需返回客户端获取更多信息。在服务器上存储HTTP调用的结果不是状态,而是缓存


现在,考虑到基于REST的API可能不是最适合您使用的API,如果您仍然想使用它,这里是您的选项:

1。将查询字符串与通用URL操作一起使用

您可以使用Querystring,但可以简化资源路径,以接受单个URI上的所有转换。考虑到您的示例和不愿意存储转换后的结果,这可能是您的最佳选择

GET http://my.api/data/123/transform?add=10&multiply=5
2。非RESTfully使用POST

您可以使用POST请求,并利用HTTP正文发送转换参数。这将确保在您决定进行大量处理时,不会耗尽查询字符串上的空间,并且还将保持通信整洁。如果POST返回图像数据,则不认为这是RESTful

3。使用POST RESTfully

最后,如果您决定要缓存东西,那么POST实际上可以存储转换后的对象(请注意,REST并不指定如何将其存储在内存或数据库等中),可以使用GET通过Id重新获取该对象

选项A

发布到URI将创建一个从属资源

返回

201 Created
Location: http://my.api/data/123/edit/{uniqueid}
201 Created
Location: http://my.api/data/{uniqueid}
然后获取编辑后的数据

GET http://my.api/data/123/edit/{uniqueid}
GET http://my.api/data/123/edit/{uniqueid}
GET http://my.api/data/{uniqueid}
选项B

从URL中删除资源标识符,以明确您正在创建新项目,而不是更改现有项目。生成的URL也与原始URL处于相同的级别,因为它假定它是相同类型的结果

返回

201 Created
Location: http://my.api/data/123/edit/{uniqueid}
201 Created
Location: http://my.api/data/{uniqueid}
然后获取编辑后的数据

GET http://my.api/data/123/edit/{uniqueid}
GET http://my.api/data/123/edit/{uniqueid}
GET http://my.api/data/{uniqueid}

有多种方法可以做到这一点。最终它应该是干净的,不管你想给它贴什么标签(REST非REST)。REST不是一个带有RFC的协议,所以不要太担心您是如何将信息作为URL路径或URL参数传递的。底层Web服务应该能够为您获取数据,而不必考虑数据的传递方式。例如,Java Jersey将为您提供参数,无论它们是参数还是URL路径,这只是注释的不同

回到您的具体问题,我认为这个REST类型调用中的资源与其说是用于对其执行数字运算的数据,不如说是实际响应。在这种情况下,数据ID和操作是字段的POST就足够了

POSThttp://my.api/operations/

{
    "dataId": "123",
    "operations": [
        {
            "type": "add",
            "value": 10
        },
        {
            "type": "multiply",
            "value": 5
        }
    ]
}
正如您所指出的,响应必须指向可以检索结果的位置。由位置(和)引用的结果
GET http://my.api/image/{image_id}/operations/{geyscale_id}
GET http://my.api/image/{image_id}/operations/flip
GET http://my.api/data/{id1},{id2}/operations/{some_operation}
GET http://my.api/data/{id1}/operations/{some_operation},{another_operation}