json - REST API - 文件(即图像)处理 - 最佳实践

我们正在使用 REST API 开发服务器,它接受和响应 JSON。问题是,如果您需要将图像从客户端上传到服务器。

注意:我也在谈论一个用例,其中实体(用户)可以有多个文件(carPhoto、licensePhoto)并且还有其他属性(名称、电子邮件...),但是当您创建新用户时,您不发送这些图像,它们是在注册过程之后添加的。


我知道的解决方案,但每个都有一些缺陷

1.使用 multipart/form-data 代替 JSON

good : POST 和 PUT 请求尽可能 RESTful,它们可以包含文本输入和文件。

缺点:它不再是 JSON,与 multipart/form-data 相比,它更容易测试、调试等

2。允许更新单独的文件

用于创建新用户的 POST 请求不允许添加图片(在我们的用例中我一开始说的那样可以),上传图片是通过 PUT 请求作为 multipart/form-data 完成的,例如/users/4/汽车照片

:一切(除了文件上传本身)都保留在 JSON 中,易于测试和调试(您可以记录完整的 JSON 请求而不必担心它们的长度)

缺点 : 这不直观,您不能一次 POST 或 PUT 实体的所有变量,而且这个地址 /users/4/carPhoto 可以被视为更多一个集合(REST API 的标准用例类似于 /users/4/shipments)。通常你不能(也不想)GET/PUT 实体的每个变量,例如 users/4/name 。您可以使用 GET 获取名称并在 users/4 使用 PUT 更改它。如果id后面有东西,一般是另外一个集合,比如users/4/reviews

3.使用 Base64

以 JSON 格式发送,但使用 Base64 编码文件。

good :和第一个解决方案一样,它尽可能是 RESTful 服务。

缺点:再一次,测试和调试更糟糕(主体可能有兆字节的数据),客户端和服务器的大小和处理时间都会增加 p>


我真的很想使用解决方案号。 2,但它有它的缺点......任何人都可以让我更好地了解“什么是最好的”解决方案?

我的目标是让 RESTful 服务包含尽可能多的标准,同时我想让它尽可能简单。

最佳答案

OP here(两年后我在回答这个问题,Daniel Cerecedo 的帖子一次还不错,但是网络服务发展很快)

经过三年的全职软件开发(同时专注于软件架构、项目管理和微服务架构)我肯定会选择第二种方式(但有一个通用端点)作为最佳方式.

如果您有一个特殊的图像端点,它会为您提供更多处理这些图像的权力。

我们为移动应用程序(iOS/android)和前端(使用 React)提供了相同的 REST API (Node.js)。这是 2017 年,因此您不想在本地存储图像,而是想将它们上传到某个云存储(Google 云、s3、cloudinary ......),因此您需要对它们进行一些常规处理。

我们的典型流程是,一旦您选择了一张图片,它就会开始在后台上传(通常是在/images 端点上发布),上传后返回您的 ID。这对用户来说非常友好,因为用户选择了一张图片,然后通常会继续处理其他一些字段(即地址、姓名等),因此当他点击“发送”按钮时,图片通常已经上传。他没有等待,而是看着屏幕说“正在上传……”。

获取图像也是如此。特别是由于手机和有限的移动数据,您不想发送原始图像,您想发送调整大小的图像,因此它们不会占用那么多带宽(并且为了使您的移动应用程序更快,您通常不希望要完全调整它的大小,您希望图像完全适合您的 View )。出于这个原因,优秀的应用程序会使用 cloudinary 之类的东西(或者我们确实有自己的图像服务器来调整大小)。

此外,如果数据不是私有(private)的,那么您只需将 URL 发送回应用程序/前端,然后它会直接从云存储下载,这可以为您的服务器节省大量带宽和处理时间。在我们更大的应用程序中,每个月都会下载大量 TB,您不想直接在每个专注于 CRUD 操作的 REST API 服务器上处理这些数据。您想在一个地方处理(我们的 Imageserver,它有缓存等),或者让云服务处理所有这些。


缺点:您应该想到的唯一“缺点”是“未分配图像”。用户选择图像并继续填写其他字段,但随后他说“不”并关闭应用程序或选项卡,但同时您成功上传了图像。这意味着您上传的图片没有分配到任何地方。

有几种处理方法。最简单的一个是“我不在乎”,这是一个相关的,如果这种情况不经常发生,或者您甚至希望存储用户发送给您的每个图像(出于任何原因)并且您不想要任何删除。

另一个也很简单 - 你有 CRON,即每周,你删除所有超过一周的未分配图像。

https://stackoverflow.com/questions/33279153/

相关文章:

c# - 在 JSON.NET 中反序列化的转换接口(interface)

json - 如何在结构中定义多个名称标签

javascript - 通过 JavaScript 动态创建 JSON 对象(没有连接字符串)

arrays - YAML 等效于 JSON 中的对象数组

android - 如何在 Android 中解析 JSON?

c# - JSON.net:如何在不使用默认构造函数的情况下反序列化?

android - 如何在 Android 中使用 HTTPClient 以 JSON 格式发送 P

json - 如何在 ECMAScript 6 中导入 JSON 文件?

javascript - 如何动态创建 JavaScript 数组(JSON 格式)?

mysql - 在 MySQL 中以 JSON 格式存储数据