问题描述
我正在开发一个 json rest web 服务,该服务将从使用backbone.js 构建的单个网页应用程序使用
此 API 将允许消费者上传与某些实体相关的文件,例如与项目相关的 pdf 报告
谷歌搜索并在堆栈溢出方面进行了一些研究,我提出了以下可能的方法:
第一种方法: base64 编码的数据字段
POST:/api/projects/234/reports{作者:'xxx',摘要:'xxxx',文件名:'xxxx',文件大小:222,content: ''}
第二种方法:多部分表单发布:
POST:/api/projects/234/reports{作者:'xxx',摘要:'xxxx',}
作为回应,我会得到一个报告 ID,然后我将发布另一篇文章
POST:/api/projects/234/reports/1/contentenctype=multipart/form-data
然后只发送二进制数据
(看看这个:https://stackoverflow.com/a/3938816/47633)>
第三种方法:将二进制数据发布到单独的资源并保存href
首先我在客户端生成一个随机密钥并将二进制内容发布在那里
POST:/api/files/E4304205-29B7-48EE-A359-74250E19EFC4enctype=multipart/form-data
然后
POST:/api/projects/234/reports{作者:'xxx',摘要:'xxxx',文件名:'xxxx',文件大小:222,href: '/api/files/E4304205-29B7-48EE-A359-74250E19EFC4'}
(参见:https://stackoverflow.com/a/4032079/47633)
我只是想知道是否还有其他方法可以使用,每种方法的优缺点,以及是否有任何既定的方法来处理此类要求
我认为第一种方法的最大缺点是我必须在客户端完全加载文件并对其进行 base64 编码
一些有用的资源:
- 将二进制数据发布到 RESTful 应用程序
- 将二进制数据传输到 HTTP REST API 服务的好方法是什么?
- 如何使用 REST 网络服务上传包含元数据的文件?
- 使用网络服务传输大型有效负载的坏主意?
- https://stackoverflow.com/a/5528267/47633
我的研究成果:
单个请求(包含数据)
请求包含元数据.数据是元数据的一个属性,经过编码(例如:Base64).
优点:
- 事务性
- 每次都有效(没有丢失元数据或数据)
缺点:
- 编码使请求非常大
示例:
单个请求(多部分)
请求包含一个或多个包含元数据和数据的部分.
内容类型:
优点:
- 事务性
- 每次都有效(没有丢失元数据或数据)
缺点:
- 内容类型协商很复杂
- 数据的内容类型在 WADL 中不可见
示例:
- Confluence(包含数据和元数据部分)
- Jira(数据只有一部分,文件名和 MIME 类型只有元数据部分标题)
- Bitbucket(只有一部分是数据,没有元数据)
- Google 云端硬盘(其中一部分用于元数据和一个用于零件数据)
单个请求(HTTP 标头和 URL 中的元数据)
请求正文包含数据和 HTTP 标头,URL 包含元数据.
优点:
- 事务性
- 每次都有效(没有丢失元数据或数据)
缺点:
- 不可能有嵌套的元数据
示例:
两个请求
一个元数据请求和一个或多个数据请求.
优点:
- 可扩展性(例如:数据请求可以转到存储库服务器)
- 可恢复(例如参见 Google Drive)
缺点:
- 非交易性
- 并非每次都有效(在第二次请求之前,缺少一部分)
示例:
I'm developing a json rest web service that will be consumed from a single web page app built with backbone.js
This API will let the consumer upload files related to some entity, like pdf reports related to a project
Googling around and doing some research at stack overflow I came with these possible approaches:
First approach: base64 encoded data field
POST: /api/projects/234/reports
{
author: 'xxxx',
abstract: 'xxxx',
filename: 'xxxx',
filesize: 222,
content: '<base64 encoded binary data>'
}
Second approach: multipart form post:
POST: /api/projects/234/reports
{
author: 'xxxx',
abstract: 'xxxx',
}
as a response I'll get a report id, and with that I shall issue another post
POST: /api/projects/234/reports/1/content
enctype=multipart/form-data
and then just send the binary data
(have a look at this: https://stackoverflow.com/a/3938816/47633)
Third approach: post the binary data to a separate resource and save the href
first I generate a random key at the client and post the binary content there
POST: /api/files/E4304205-29B7-48EE-A359-74250E19EFC4
enctype=multipart/form-data
and then
POST: /api/projects/234/reports
{
author: 'xxxx',
abstract: 'xxxx',
filename: 'xxxx',
filesize: 222,
href: '/api/files/E4304205-29B7-48EE-A359-74250E19EFC4'
}
(see this: https://stackoverflow.com/a/4032079/47633)
I just wanted to know if there's any other approach I could use, the pros/cons of each, and if there's any established way to deal with this kind of requirements
the big con I see to the first approach, is that I have to fully load and base64 encode the file on the client
some useful resources:
- Post binary data to a RESTful application
- What is a good way to transfer binary data to a HTTP REST API service?
- How do I upload a file with metadata using a REST web service?
- Bad idea to transfer large payload using web services?
- https://stackoverflow.com/a/5528267/47633
My research results:
Single request (data included)
The request contains metadata. The data is a property of metadata and encoded (for example: Base64).
Pros:
- transactional
- everytime valid (no missing metadata or data)
Cons:
- encoding makes the request very large
Examples:
Single request (multipart)
The request contains one or more parts with metadata and data.
Content types:
Pros:
- transactional
- everytime valid (no missing metadata or data)
Cons:
- content type negotiation is complex
- content type for data is not visible in WADL
Examples:
- Confluence (with parts for data and for metadata)
- Jira (with one part for data, metadata only part headers for file name and mime type)
- Bitbucket (with one part for data, no metadata)
- Google Drive (with one part for metadata and one for part data)
Single request (metadata in HTTP header and URL)
The request body contains the data and the HTTP header and the URL contains the metadata.
Pros:
- transactional
- everytime valid (no missing metadata or data)
Cons:
- no nested metadata possible
Examples:
Two request
One request for metadata and one or more requests for data.
Pros:
- scalability (for example: data request could go to repository server)
- resumable (see for example Google Drive)
Cons:
- not transactional
- not everytime valid (before second request, one part is missing)
Examples:
这篇关于设计带有从浏览器消费的二进制数据的休息 Web 服务的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!