REST API并提供二进制资源

时间:2012-08-29 19:51:50

标签: rest

使用REST API提供二进制资源(如pdf文件)的惯例是什么?您是否只是在JSON或XML响应中返回资源的URL,例如{“url”:“http://example.com/document.pdf”}?

我正在尝试理解URI和URL之间的区别,并遵循RESTful理念。不可否认,这对我来说是新的,所以我可能会误解一些事情。

3 个答案:

答案 0 :(得分:10)

此部分假设您的意思:如何告诉用户在哪里找到二进制资源

URI和URL之间的区别与二进制与非二进制数据类型(see also)没有任何关系。

如果您主要返回JSON,那么url条目是常用的方法。如果您正在做更多HTML / XML-ish的事情,那么具有良好<link>属性的rel元素之类的内容非常有意义。

显然,如果客户端向您提供的直接URL发出GET请求,那么您应该向他们发送文件,除非他们发送了一堆内容协商标头,这些标头有效地阻止您完成他们的请求。在这种情况下,406 Not Acceptable响应(或the official definition)很有意义。

如果您的问题意味着其他问题,请澄清。

漫步“喜欢这个”部分

首先:忽略URL与URI。它与此没有任何关系。完全没有。

下一步:如果您的问题不是“我如何链接到资源”(可能会受到我即将讨论的内容的影响),但“如果我的资源只是一个PDF文件怎么办”,那么解决它的各种选择。首先,你需要退后一步,思考一下(一点点)。您的资源几乎肯定不是“PDF文件”。它是“用户上传的文件”,或“我生成的报告的PDF版本”等。

在第一种情况下,您可能没有超出他们发送给您的二进制文件的任何资源表示,这是完全正常的。当您收到该资源的URL GET时,您可能不需要执行任何类型的内容协商。只需向他们发送文件,但需遵守上面提到的关于406的警告。

在第二种情况下,您可能拥有此资源的各种表示形式:CSV,HTML,LaTeX,您可以为其命名。在这种情况下,当您收到资源的网址GET时,您需要进行一些内容协商,因此您知道是否要向他们发送PDF文档或其他内容其他。您可能拥有资源的JSON表示,该表示只是用于生成PDF的原始数据。

在任何一种情况下,如果您的表示都是严格的资源元数据,则会出乎意料。如果需要(通常是,有时不是),显式的外部元数据(与嵌入在二进制资源中的元数据相反,例如PDF中的作者和标题信息)最常被建模为单独的资源。

最后,正如@monitorjbl所说:你可能不希望直接以文本格式(如JSON或XML)嵌入二进制数据。有办法,通常涉及“base64编码”这个词,但它通常不是最好的方法。通常,您不应混合使用二进制数据和文本数据。

答案 1 :(得分:5)

二进制与否,您的REST资源应该用超媒体类型来描述。

  • 如果您的REST客户端以msgpack格式PUT / POST资源,则REST服务器仍然可以读取此消息并更新/创建资源。那么为什么不呢。
  • 如果你的REST客户端以PDF格式输入/发布资源,我猜你将无法提取正确创建/更新资源所需的所有信息。所以,没有。

在最后一种情况下,您可能正在处理类似“Google驱动器”的服务:这些PDF本身不是您的资源,应该通过您的实际资源进行链接(即URL应该在您的资源中) )。

即使Google Drive可能不是完美的REST API (API reference),它也会处理JSON资源和实际的二进制文件。

答案 2 :(得分:2)

根据我的经验,这样做会与REST Web服务的想法相对立。与传统的RESTful服务不同,您永远不会在没有严重头痛的情况下缓存此响应。此外,由于您必须以文本形式使用服务才能读取XML / JSON,因此您可能无法针对文本和二进制读取进行优化。更不用说,你必须总是需要二进制信息,或者当你只需要文本数据时,你将在性能上受到重大影响。如果您总是需要二进制数据,也许可以问问自己为什么需要Web服务?

这并不是说它是不可能的(毕竟还有BSON)或者说这个用例是不存在的,但你应该确定你无法逃避强制单独请求二进制数据在你尝试这样做之前。将二进制数据嵌入到为文本设计的文档格式中效率非常低,而且这种形式的数据要比原始字节大得多。

顺便说一句,如果您总是使用SVG等矢量图形资源或某些类型的PDF来执行此操作,则可以将其表示为XML数据。同样,您可能不想这样做,因为它会增加您的有效负载,但它可以选择绕过“需要二进制”的东西。