繁体   English   中英

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

[英]Proper way to implement RESTful large file upload

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

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

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

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

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

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

总结亚马逊使用的程序:

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

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

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

亚马逊还提供了中止上传的方法,并列出了与上传相关联的块。 如果上载未在一定时间内完成,您可能还需要考虑上传请求的超时,在该超时请求中销毁块。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM