跳转到主要内容
Chinese, Simplified

自 1980 年代以来,我一直在为计算机编程。在那段时间里,我看到并使用了很多来来去去的语言和技术。我看着 Web 涌现出大量新功能,例如浏览器异步交换 XML 数据。今天我们称这种异步 JavaScript 和 XML 数据交换为“AJAX”,但具有讽刺意味的是,AJAX 通常不再使用 XML。大多数情况下,这些数据以 JSON、YAML、HTML 或其他一些格式进行交换。
1996 年,微软工程师在 IE4 中引入了 iframe 标签。这允许浏览器在不刷新页面的情况下与相同或完全不同的服务器异步交换数据,并且该数据可以传递给生成 iframe 对象的父对象。
当时,这个新功能对我来说似乎只不过是一个神奇的“框架”功能(我知道,你不知道 HTML 框架是什么;是的,我已经那么老了,谢谢提醒)。然而,我的兄弟在 1990 年代中期在商业项目中使用了这项技术——甚至在术语“AJAX”发明之前就使用 XML 进行“AJAX”数据调用。
几年后,Microsoft 将在 IE5 中创建 XMLHttpRequest 对象。其他浏览器厂商纷纷效仿,“AJAX”时代诞生了。

REST 正在消亡。摆脱它。


有时,标准和技术的发明是出于以下原因而生根发芽的:好的、坏的和丑陋的。 REST 是这些标准之一,它体现了所有三个方面:好的、坏的和丑陋的。但是每个人都继续使用 REST,因为这是现代客户端(浏览器)实现的。
我对 REST 的主要问题是它的动词:GET、POST、PUT、DELETE 等,限制太多,响应经常不一致,或者根本没有响应,就像 DELETE。是的,您可以使用 DELETE 调用返回成功响应(意味着数据有效负载),但这并不是真正的标准。哦,您收到了 200 条回复,这意味着它有效。不是。也许有,也许没有。发送 202 或 204 响应可能同样神秘。
公平地说,REST 本身实际上并不是一种数据交换协议,例如 SOAP。它实际上是一种架构风格,或者有人会说“模式”。作为软件开发人员,有时我们会明确地遵循风格/模式,有时则不会。

标准如果有效就很好。但是随着技术使用的进步,“标准”通常开始阻碍您,这就是 REST 对网络所做的。
除了动词的限制之外,我在 REST 中遇到的另一个问题是它的端点。谁认为拥有 37 个不同的端点是个好主意?
REST 本身也没有实现 API 文档,就像 SOAP 与 WSDL 一样。是的,OpenAPI 规范(前身为 Swagger)试图解决这个问题,但它是另一个 REST 补充。


由于 REST 的这一限制和其他限制,许多软件工程师使用小块 REST 和/或借鉴其他工作得更好的协议来开发和发展我们自己的 Web 服务版本,我也不例外。


TIGER:更简单、更有效的 Web 服务


TIGER 是我为大约 12 年前开发的一个松散的 Web 服务标准创造的名字,因为我厌倦了 REST 的局限性和废话。 TIGER 松散地基于一种 JSON-RPC(JSON 远程过程调用)协议,该协议实际上仅使用 REST 的 POST 和/或 GET 动词通过浏览器客户端发送和接收数据。如果您愿意,可以使用 GET 快速获取数据,但 POST 几乎专门用于安全地交换数据。
TIGER 利用易于使用的“消息模式”将数据发送和路由到需要去的地方。路由元数据包含(混合)在到服务器的“消息”中。
因此,TIGER 只需要一个端点。
是的,您可以拥有多个端点,但您不应该这样做。拥有一个带有许多端点的 API 会造成巨大的代码膨胀,就像我们在典型的 RESTful 服务中看到的那样。 Zend 甚至创建了一个名为“Apigility”的完整 REST 框架来管理和进一步膨胀 API 端点。这是胡说八道。保持简单的事情发生了什么?
TIGER 真正闪耀的地方是在面向服务的 MVC 应用程序的上下文中。您的 AJAX 数据消息不是设置多个端点,而是简单地包含 MVC 的控制器 /action,或者在 SOA(面向服务的架构)的情况下,您希望以数据负载为目标进行处理的服务/方法。繁荣!完毕。


如果您愿意,您还可以在消息元数据中包含诸如版本属性之类的内容,以针对特定服务版本。
TIGER Webservices 背后的主要目标是:

  • 为 API 创建一个单一且安全的入口点,这样我就不必管理和维护数十个版本化端点,从而使我的代码膨胀。
  • 自动验证、路由和授权通过 API 传入的请求。
  • 在客户端和服务器消息和响应之间创建灵活但一致的契约。

TIGER 服务通常是有状态的。但是,如果您愿意,它们可以完全无状态。你不会限制某人对 API 应该如何表现的想法。

在 MVC 上下文中运行的 TIGER 必须将每个匿名请求验证为“来宾”,或者作为其他经过身份验证的角色以进行授权。 如果您无权访问您请求的任何资源,您将无法进入。
在这方面,TIGER Webservices 确实依赖于维护某种会话状态的客户端,但无论如何我们已经对各种 RESTful 服务这样做了,因此 TIGER 在这方面没有什么不同。


TIGER Webservices  在行动


这里的概念非常简单。 图案之美就在于此:

Tiger

以下是使用 jQuery 调用的典型 TIGER AJAX 请求:

$.ajax({
    type        : 'POST',
    url         : '/api',
    dataType    : 'json',
    data        : { 
                      service   : 'user',
                      method    : 'save',
                      firstname : 'Thundarr',
                      lastname  : 'Barbarian'
                  },
    beforeSend  : beforeSend,
    complete    : complete,
    success     : success,
    error       : error
});

请注意,beforeSend、complete、success 和 error 只是表示将处理这些 AJAX 事件的函数的 JavaScript 变量。
在这个简单的例子中,我们看到我们将 JSON 数据发布到服务器唯一的 /api 端点。 TIGER API 服务期望在消息数据中看到的是“服务”和“方法”属性。然后它将整个消息数据对象路由到该特定服务和方法。
您还可以传递“controller”和“action”属性,TIGER 会将数据路由到 MVC 中任何控制器的特定操作。
在这个示例调用中,我们联系了“user”服务的“save”方法以将用户的“firstname”和“lastname”字段保存在数据库中。没有比这更简单的了。


TIGER API 路由


每个 API 调用都通过 API 服务进行路由。 API 服务实现了一个基本的工厂模式来进行一些健全性检查、验证、授权,然后实例化请求的控制器或服务。
在 TIGER 平台的情况下,我使用 PHP 的 __construct() 方法在构造时将整个消息传递到服务中,并让服务从那里将消息路由到任何方法。
以这种方式处理数据很酷的一点是,当新实例化的服务最终返回时,所有的工作都已经完成,我需要做的就是为响应负载调用服务的 getResponse() 方法,我们就完成了.
好的,所以它只是在工厂流程中为我节省了一步,但它仍然是在 PHP 中实现 SOA 的一种灵活的可扩展方式。但我离题了……


TIGER 的反应


TIGER 的美妙之处在于我每次都返回完全相同的响应对象。该响应对象始终具有我期望的属性。它就像一个接口,客户端和服务器之间的契约。在响应对象中,我知道我总能找到至少以下属性:

{
    result   : 1,  // or 0 on error
    data     : { ... },  // can also be an array
    messages : ['An array of one or more messages, if any.'],
    error    : [ array of form errors, if any ]
}

但您也不仅限于一种类型的响应。例如,DataTables 和 Select2 要求我返回不同类型的响应供它们使用。没问题。我有单独的一致响应对象来发送回这些类型的数据请求。


把它放在一起


我不想在本文中发布大量代码,因此如果您想查看 TIGER Webservices 的实际应用,请查看 GitHub 上使用这些服务的 TIGER 平台。这里有几个链接:

请注意,上述代码受版权保护,因为它是商业产品的一部分,但模式本身不受版权保护。随意“借用”这些想法并编写自己的版本。 TIGER 代码特别公开,因为我希望人们看到 TIGER Webservices 的易用性以及它们如何在构建 Web 服务时让每个人的生活更轻松。
[无耻的产品插件警告:]如果您有AWS帐户,您还可以免费启动TIGER平台实例以查看TIGER Webservices的运行情况。 【广告结束。】


TIGER 发现


虽然我还没有为 TIGER 实现 OpenAPI 风格的“发现”模式或标准,但您可以看到使用 TIGER 的消息模式将使发现变得基本,只需传入一个元数据属性,告诉 TIGER 返回任何 API 文档和响应模型类型你想要。如果你需要实现一个公共API,这不是一个很难解决的问题。


结论


随着网络的不断发展,REST 正在并且应该随着新的更好的想法的出现而慢慢消亡。 JSON 几乎完全取代了 XML。微服务正成为更加单一的面向服务架构的一种更流行的变体;等等。现在是我们超越 REST 并获得更大灵活性的时候了。
如果可以避免,我不会使用纯 RESTful 服务,如果没有其他原因,因为代码膨胀;这种膨胀简直是无稽之谈。
有些人可能会争辩说 TIGER Webservices 太“松散”并且不遵守任何“公认的”标准。你是对的,他们没有,而且有充分的理由。我不喜欢我所看到和使用的标准。他们很烂。所以我不使用它们。作为应用程序架构师,我自己编写。你也可以。您不必仅仅因为其他人都这样做而使用一些古怪的过时标准。
您的用例应该驱动技术,而不是相反。
关键是,仅仅因为某些东西是所谓的“公认”标准并不意味着它是完美的,或者它最适合您的应用程序的用例。经验会告诉你什么最有效,什么无效。某些东西不必是“公认的标准”,只要它有据可查,并且可以为您的独特用例简化代码。
今天有比 REST 更好的模式和协议来在客户端和服务器之间交换数据。查看 TIGER Webservices 及其工作原理。他们可能只是给你一些你自己的想法,这些想法可以让一两年后其他工程师的编码变得更加容易。

原文:https://javascript.plainenglish.io/rest-is-dying-get-rid-of-it-d43e6ef8…

本文:https://jiagoushi.pro/node/1638

Article
知识星球
 
微信公众号
 
视频号