我觉得有点悲哀地看到,经过10年以上没有答案真的,说明如何作为OP要求这样的事情可能会在REST架构来设计的,因此我觉得有必要现在就这样做。
首先,什么是REST ?!缩写REST或ReST代表“表示状态转移”,并以某种表示格式定义资源状态的交换。表示格式符合协议的媒体类型。如果是application/html
表示形式,可能是在应用某些样式表格式将某些元素放置在某些位置之后,在浏览器中呈现的HTML格式的文本内容流。
REST原则上是众所周知的可浏览Web的概括,尽管它针对的是各种应用程序,而不仅针对浏览器。因此,通过设计,适用于Web的相同概念也适用于REST体系结构。诸如如何以“ RESTful”方式实现某些目标之类的问题解决了围绕以下问题的答案:如何在网页上实现某些目标,然后将相同的概念应用于应用程序层。
基于Web的计算器通常可以从一些“页面”开始,该页面允许您输入一些值以将输入的数据发送到服务器之前进行计算。在HTML中,这通常是通过HTML <form>
元素实现的,HTML 元素教客户如何设置可用参数,发送请求的目标位置以及在发送输入数据时应用的表示格式。这可以看起来像这样:
<html>
<head>
...
</head>
<body>
<form action="/../someResource" method="post" enctype="application/x-www-form-urlencoded">
<label for="firstNumber">First number:</label>
<input type="number" id="firstNumber" name="firstNumber"/>
<label for="secondNumber">Second number:</label>
<input type="number" id="secondNumber" name="secondNumber"/>
<input type="submit" value="Add numbers"/>
</form>
</body>
</html>
上面的示例即指出,有两个输入字段可以由用户或其他一些自动机填写,并且在调用Submit输入元素时,浏览器会负责将输入数据application/x-www-form-urlencoded
格式化为发送的表示形式POST
在这种情况下,可以通过指定的HTTP请求方法将其定位到上述目标位置。如果我们1
在firstNumber
输入字段和输入字段2
中secondNumber
输入内容,浏览器将生成的表示形式firstNumber=1&secondNumber=2
,并将其作为实际请求的主体有效内容发送到目标资源。
因此,发送给服务器的原始HTTP请求可能如下所示:
POST /../someResource
Host: www.acme.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Accept: application/html
firstNumber=1&secondNumber=2
服务器可以执行计算,并用另一个包含计算结果的HTML页面进行响应,因为请求表明客户端可以理解这种格式。
正如布雷顿已经指出的那样,不存在“ RESTful” URL或URI之类的东西。URI / URL是它自己的东西,不应向客户端/用户传达任何含义。在上面的计算器示例中,用户根本不感兴趣将数据发送到哪里,只是感兴趣的是,一旦触发了提交输入字段,请求就被发送了。服务器应该已经提供了执行任务所需的所有必需信息。
浏览器可能还没有意识到请求实际上是在向计算器提供一些输入参数,它也可能是某种订购单,它仅返回下一个表单表示以继续订购过程,或者某种完全不同的订购单。资源。在这种情况下,它只是执行HTML规范所要求的内容,因此它不会在乎服务器的实际操作。这个概念使浏览器可以使用相同的表示形式来完成所有事情,例如从您首选的网上商店订购商品,与您最好的朋友聊天,登录在线帐户等等。
某些元素的承受能力(例如通常在呈现为按钮的“提交输入”字段情况下)定义了您应该如何使用它。对于按钮或链接,它基本上会告诉您单击它。其他元素可以传达不同的能力。这种可承受性也可以通过链接关系来表示,即使用带preload
注释的链接,这些链接基本上告诉客户端它已经可以在后台加载链接资源的内容,因为用户接下来很可能会获取该内容。当然,此类链接关系应标准化或遵循Web链接定义的关系类型扩展机制。
这些是在Web上使用的基本概念,在REST体系结构中也应使用。据“鲍勃叔叔”罗伯特·C·马丁(Robert C. Martin)称,架构与意图有关,REST架构背后的意图是使客户端与服务器脱钩,以使服务器在将来自由发展,而不必担心会破坏客户端。不幸的是,这很容易受到约束,因为引入耦合或添加快速解决方案很容易完成工作并继续进行。正如吉姆·韦伯(Jim Webber)在REST体系结构中指出的那样,作为服务提供者,您应尝试设计类似于客户端将遵循的70年代基于文本的计算机游戏的域应用程序协议,直到客户到达过程结束为止。
不幸的是,现实中有很多所谓的“ REST” API只是在做这些。您会看到在特定于API的外部文档中指定的大多数基于JSON的数据交换,这些文档通常很难动态集成。请求的外观格式也被硬编码到外部文档中,这导致大量实现解释URI以返回预定义的类型而不是使用预先协商的一些常见表示格式。这样可以防止服务器更改,因为客户端现在希望接收预定义URI的某种数据格式(注意,不是表示格式!)。这种自定义数据格式交换还可以防止客户端与其他API进行交互,因为“数据格式”通常是特定API的潮流。我们从过去的RPC技术(例如Corba,RMI或SOAP)中知道了这个概念,尽管Peppol最近通过将AS2替换为AS4作为默认传输协议而再次使用它,但我们还是谴责它是邪恶的。
关于实际提出的问题,将数据作为csv文件发送与使用application/x-www-form-urlencoded
表示形式或类似内容没什么不同。吉姆•韦伯(Jim Webber)明确指出,毕竟HTTP只是一种传输协议,其应用领域是通过Web进行文档传输。客户端和服务器至少应同时支持RFC 7111中text/csv
定义的内容。可以通过处理定义了表单元素的媒体类型,将请求发送到的目标元素或属性以及执行配置上载的HTTP方法来生成此CSV文件。
有几种支持表单的媒体类型,例如HTML,HAL Forms,halform,ion或Hydra。不过,我目前尚不了解一种可以自动将输入数据text/csv
直接编码为媒体的媒体类型,因此可能需要定义一个媒体类型并向IANA的媒体类型注册中心注册。
我猜,完整参数集的上传和下载应该不是问题。如前所述,目标URI不相关,因为客户端将仅使用URI来检索要处理的新内容。按营业日期进行过滤也不难。但是,服务器在此应具有客户端可以选择的所有可能性的客户端。近年来,GraphQL和RestQL不断发展,它们引入了类似SQL的语言,可以将其定位于某个端点以获得经过过滤的响应。但是,从真正的REST的角度来看,这违反了REST的思想,因为a)GraphQL,即仅使用单个端点,这在某种程度上阻止了缓存的最佳使用,并且b)需要了解可用字段,这可能导致引入客户端耦合资源的基础数据模型。
激活或取消激活某些配置参数仅是触发提供此功能的超媒体控件。在HTML表单中,这可以是一个简单的复选框,也可以是列表中的多行选择,也可以是此类。根据其形式和定义的方法,它可能会通过发送整个配置,PUT
或者对所做的更改很精明,而仅通过进行部分更新PATCH
。后者基本上需要对更新表示的变更表示进行计算,并向服务器提供所需的步骤,以将当前表示转换为所需的表示。根据PATH规范,这必须在事务内完成,以便应用所有步骤或不应用任何步骤。
HTTP允许并鼓励服务器在应用更改之前先验证收到的请求。对于PUT,规范指出:
原始服务器应验证PUT表示是否与服务器对目标资源的任何约束一致,该约束不能由PUT更改,也不会由PUT更改。当源服务器使用与URI相关的内部配置信息以便为GET响应设置表示元数据的值时,这尤其重要。当PUT表示与目标资源不一致时,源服务器应该通过转换表示或更改资源配置来使其一致,或者使用包含足够信息的适当错误消息进行响应,以解释为什么该表示不合适。建议使用409(冲突)或415(不受支持的媒体类型)状态码,
例如,如果目标资源配置为始终具有“文本/ html”的内容类型,并且表示为PUT的表示具有“图像/ jpeg”的内容类型,则源服务器应执行以下操作之一:
一个。重新配置目标资源以反映新的媒体类型;
b。将PUT表示形式转换为与资源格式一致的格式,然后再将其保存为新的资源状态;要么,
C。使用415(不支持的媒体类型)响应拒绝该请求,该响应指示目标资源仅限于“ text / html”,可能包括指向其他资源的链接,该链接将是新表示形式的合适目标。
HTTP并未明确定义PUT方法如何影响原始服务器的状态,超出了用户代理请求的意图和原始服务器响应的语义所能表达的范围。...
总结一下,您应该使用现有的媒体类型,该媒体类型可以让您了解所需的或受支持的输入参数,向其发送请求的目标位置,要使用的操作以及媒体的媒体类型。必须格式化请求,或者定义自己的请求,并向IANA注册。如果要将输入转换为,则可能需要后者text/csv
然后将CSV表示形式上载到服务器。验证应在将更改应用于资源之前进行。实际的URI不应与客户端相关,而应确定将请求发送到何处,因此服务执行者可以自由选择。通过执行以下步骤,您几乎可以随时更改服务器端,并且如果客户端支持所用的媒体类型,客户端也不会因此而中断。