正确实现RESTful大文件上传的方法

Ale*_*vic 16 java rest curl file-upload file

我一直在制作REST API已经有一段时间了,我仍然会遇到一个案例 - 大文件上传.我已经阅读了其他一些API,比如Google Drive,Twitter和其他文献,我有两个想法,但我不确定它们中的任何一个是"正确的".正如在适当的情况下,我的意思是它有点标准化,不需要太多的客户端逻辑(因为其他方将实现该客户端),或者甚至更好,它可以通过cURL轻松调用.计划是用Java实现它,最好是Play Framework.

显然,由于文件很大,我需要一些文件分区和服务器端缓冲机制.

所以,我得到的第一个解决方案是分段上传(multipart/form-data).我得到了这种方式,之前我已经实现了这一点,但实际上在客户端模拟表单总是很奇怪,特别是因为客户端必须设置文件密钥名称,根据我的经验,这是一些东西客户有点忘记或不理解.另外,块尺寸/零件尺寸是如何规定的?什么阻止客户端将整个文件放在一个块中?

解决方案二,至少我理解的,但没有找到实际的实现实现是"常规"POST请求可以工作.内容应该分块,数据在服务器端缓冲.但是,我不确定这是一个正确的理解.数据实际上是如何分块的,上传是跨越多个HTTP请求还是在TCP级别上进行分块?什么是Content-Type

最重要的是,这两个(或其他什么?)应该是一个客户友好的,广泛可理解的实现REST API文件上传的方式?

小智 8

https://tus.io/是可恢复协议,有助于块上传和超时后恢复上传。这是一个开源实现,已经有不同语言的各种客户端和服务器实现。


cra*_*obw 5

我建议您看一下Amazon S3 Rest API的分段文件上传解决方案。该文档可在此处找到。

总结Amazon使用的过程:

  1. 客户端发送请求以启动分段上传,API会以上传ID进行响应

  2. 客户端上载每个文件块的零件号(以保持文件的顺序),零件的大小,零件的md5哈希和上传ID;这些请求中的每一个都是一个单独的HTTP请求。API通过对照客户端提供的md5哈希检查接收到的md5哈希数据块来验证该数据块,并且该数据块的大小与客户端提供的大小相匹配。该API会以该块的标签(唯一ID)作为响应。如果您在多个位置上部署API,则需要考虑如何存储块,然后以透明的方式访问它们。

  3. 客户端发出一个完成上传的请求,其中包含每个块编号的列表以及从API接收到的相关块标记(唯一ID)。API会验证没有丢失的块,并且块编号与正确的块标签匹配,然后组合文件或返回错误响应。

Amazon还提供了中止上传并列出与上传相关联的块的方法。您可能还需要考虑上载请求的超时,如果在一定时间内未完成上载,则这些块将被破坏。

在控制客户端上载的块大小方面,您对客户端决定拆分上载的方式没有太多控制权。您可以考虑为上传配置最大块大小,并为包含大于最大大小的块的请求提供错误响应。

我发现该过程非常适合处理REST API中的大文件上传,并简化了与文件上传相关的许多极端情况的处理。不幸的是,我还没有找到一个可以轻松实现任何语言的库,因此您几乎必须自己编写所有逻辑。