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

时间:2015-11-24 09:06:34

标签: java file rest curl file-upload

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

显然我需要一些文件分区和服务器端缓冲机制,因为文件很大。

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

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

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

2 个答案:

答案 0 :(得分:4)

我建议您查看Amazon S3 Rest API的多部分文件上传解决方案。可以找到文档here

总结亚马逊使用的程序:

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

  2. 客户端使用部件号上传每个文件块(以维护文件的顺序),部件的大小,部件的md5哈希值和上传ID;这些请求中的每一个都是单独的HTTP请求。 API通过检查md5散列接收的块与客户端提供的md5散列以及块的大小是否与客户端提供的大小相匹配来验证块。 API使用块的标记(唯一ID)进行响应。如果您跨多个位置部署API,则需要考虑如何存储块,然后以位置透明的方式访问它们。

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

  4. 亚马逊还提供了中止上传的方法,并列出了与上传相关联的块。您可能还想考虑上传请求的超时,如果上传未在一定时间内完成,则会破坏块。

    在控制客户端上传的块大小方面,您无法控制客户端如何决定拆分上载。您可以考虑为上载配置最大块大小,并为包含大于最大大小的块的请求提供错误响应。

    我发现这个过程非常适合处理REST API中的大文件上传,并且有助于处理与文件上传相关的许多边缘情况。不幸的是,我还没有找到一个可以用任何语言轻松实现的库,所以你几乎必须自己编写所有的逻辑。

答案 1 :(得分:0)

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