2025年webflux优缺点(webflux太难用了)

webflux优缺点(webflux太难用了)restful 我不喜欢 RESTful 原理和 API 近年来 它被视为进程间通信的通用协议 尤其是在分布式系统中 但是 我看到 REST 的许多缺陷 对于某些用例 还有一些替代方法可以很好地发挥作用 显然 没有一个适合所有人的大小 我只想强调一下 REST 体系结构在许多方面都有缺陷 REST 的事实上的标准格式是 JSON 至少在 XML 和信封方面 它比 SOAP 更好

大家好,我是讯享网,很高兴认识大家。



restful

我不喜欢RESTful原理和API。 近年来,它被视为进程间通信的通用协议,尤其是在分布式系统中。 但是,我看到REST的许多缺陷,对于某些用例,还有一些替代方法可以很好地发挥作用。 显然,没有一个适合所有人的大小 ,我只想强调一下REST体系结构在许多方面都有缺陷。

REST的事实上的标准格式是JSON。 至少在XML和信封方面,它比SOAP更好。 要么浪费大量的网络带宽(可能是移动设备或大型数据中心的问题),要么将CPU花费在压缩和解压缩上。 一个可爱的报价:

[该]互联网在调试模式下运行的源


讯享网

这是一个严重的问题,请问高频交易者如何解析基于文本的FIX有多困难。 有很多行之有效的二进制协议,它们既易于解析又占用很少的内存,例如Protocol buffers , Avro或Thrift 。 此外,它们内置了向后兼容性。 从技术上讲,您可以将Google协议缓冲区与基于Spring MVC的REST服务结合使用 -但很少有人采用这种方式并坚持使用JSON。

当然JSON有一个(从字面上看, 一个 )巨大的优势-它是人类可读。 好吧,至少只要印刷精美即可 -很少有这种情况。 但是,我们是否真的要为此付出代价,而不是默认情况下仅使用二进制格式,并在需要人工干预时使用翻译器或切换器?

我属于静态打字营。 当我的编译器甚至在运行单元测试之前就发现错误时,我就非常喜欢它-而且我不需要一开始就编写很多错误。 而且,尤其是在函数式编程中,如果代码可以编译,则它很有用,因为按类型强制执行的契约是如此严格。 在处理XML时,我很高兴对XSD进行验证,以便可以确保我阅读的内容符合合同规定。 我可以减少断言的数量并使代码更短。 同样,我产生的XML也保证在语法上是正确的。 最后但并非最不重要的一点是,在使用关系数据库时,严格的架构可以防止我通过插入不正确的值来破坏数据。 与XML相似,我也可以相信自己读到的内容:外键正确,NOT NULL列实际上不为空,等等。这些显然是机器强制合同的优点。 在设计由分布式系统中的机器(以及偶然地在许多无模式的NoSQL数据库(如MongoDB)中)生成和使用的API时,所有这些都不是很重要。

对SOAP的可理解的憎恨将我们推向另一个极端–根本没有合同。 没有广泛的标准来记录合同并为REST API自动执行合同。 我最近发现的大多数API只是示例请求和响应的集合,充其量是Swagger 。 我不知道哪些字段是可选的,格式和约束是什么。 有人可能会说这是设计使然,我们不会将自己与一个具体的API耦合,而是会不断发展。 但是我有一种感觉,尽管如此,大多数API使用者都是耦合在一起的,一旦推出了未记录和未声明的更改,它们就会崩溃。

谈论文档时,纯粹主义者声称API应当公开的唯一信息就是根URI,例如www.example.com/api 。 其他所有内容,包括允许的方法,资源,内容类型和文档,都应通过HATEOAS发现。 而且,如果未正式记录URI,而是应该发现URI,则表明我们不应在代码中依赖硬编码的URI,而应在每次使用此类API时遍历资源树。 这是惯用的,但是也很慢且容易出错。 更不用说Swagger,这是REST文档的事实上的标准,正式宣称这种方法不是“ 按设计 ”, 而是坚持使用固定的URI。

RESTful Web服务本身不支持API的许多企业级功能,例如批处理请求,分页,排序,搜索等。 有一些竞争性的建议,例如查询参数,请求标头等。我记得我们花了一个小时的时间讨论有关灵活搜索API的问题。 应该有:

  • 单个类似于SQL的参数(带有正确的转义!),例如query=age>10 and (name=John or company=Foo)
  • 每个条件有多个参数,例如age=10&name=John&company=Foo (但是如何实现OR运算符?)
  • 最奇怪的是: /searches上的状态POST具有使用类似JSON的结构建模的条件,将URL返回到搜索结果( /searches/25 ),稍后可以查询

REST确实限制了这里。

RESTful Web服务是面向CRUD的,而不是面向业务或事务的。 无数次,我们不得不仔细地将业务术语映射到简单的创建 / 更新 / 删除操作中。 世界并不是那么简单,并不是所有事物都可以用创建或更新语句来简单描述。 即使可以,RESTful端点通常也很尴尬和人为。 您还记得POST到/searches吗? 而且,并非所有数据都可以映射到URI树结构中,并且我们经常允许非规范化,例如,同一资源在多个URI下可用,因此可以轻松访问。 想象一下一个发布域事件,任意状态更改的系统,例如LoanApproved , EmailSent等。当然,每个事件都有其自己独特的属性集。 您如何设计使用此类事件的RESTful API? 不可避免地,您将最终得到POST /domainEvents ,它接受任意JSON,也许带有诸如”type”: “LoanApproved”标记。 因此,您有一个采用任意JSON“ BLOB”的终结点,并且很可能具有类似于switch的巨型语句,可以正确解释各种类型的事件。 用”method”替换”type” ,您刚刚重新发明了JSON RPC 。 您将如何以惯用的方式做到这一点? 将发布者方面的每个域事件转换为适当的API调用? 听起来不是很健壮。

从业务术语到POST / PUT / PATCH / DELETE / HEAD的映射既繁琐又幼稚。 就像URI一样,世界更加丰富,而且并非所有内容都适合这些存储桶。 这些动词旨在与万维网中的文档和表格进行交互。 使用REST就像将我们的业务领域降级到数据库浏览器一样。 没有逻辑,没有域驱动的设计,没有丰富的流程。 我们只是操纵对象,来回移动它们。 当然,REST不必也不应直接映射到数据库实体。 但是,即使它们映射到您的核心业务域,您仍然必须通过有限的CRUD界面查看域。

通过REST发出业务错误的信号通常应使用4xx类状态码。 但是,这些错误并非旨在指示业务案例,因此我不断发现自己试图将4xx代码映射到业务结果。 验证码测试失败? 让我们将其设为400 错误请求 。 表单验证错误? 417 期望失败了 ? 是否因重复而违反约束? 409 冲突 ? 但是乐观锁异常呢? 如果客户的余额不足怎么办? 如果…该怎么办?这些错误代码是为文档检索而设计的,而不是后端的丰富业务。 最后,您将所有内容置于相同的状态代码下或构建复杂的翻译文档。 我们发明了异常,错误Either<T> –只是将自己突然限制在固定的数字错误代码集上。

404特别成问题,因为它是如此普遍。 使用RESTful API时,您永远无法判断404是商业环境还是URL中的错字。 听起来像是分布式调试地狱的秘诀。 哦,我有没有提到没有编码错误的标准方法?

RESTful API确实在微服务爱好者中很流行。 但是,让我们回到基础。 RESTful API基于HTTP,HTTP是建立在TCP / IP之上的请求-响应协议。 TCP / IP在面向数据包的IP协议之上构建连接抽象。 IP几乎无法将消息从一台计算机传递到另一台计算机。 通过构建所有这些抽象级别,我们忘记了Web确实是异步的。 我们相信,通过使用无合同的宽松JSON,我们不再将系统耦合在一起。 但是耦合还有另一个维度:时间依赖性。 如果一个系统需要通知另一个事件,那么它们是否确实确实需要同时存在。 在某些情况下(通常使用GET实现),请求-响应很有意义。 但是在大多数情况下,我们真正想要的是一劳永逸,一次最少的语义。 消息驱动的分布式体系结构被证明更加健壮和容错。 两个系统不再需要彼此见面并同时生活。 而且,如果一个系统产生过多的请求,它将不再破坏另一个系统。 只需在两个系统之间放置一个持久队列。 这种方法具有许多优点:

  • 生产者和消费者可以随时重启,而不会导致数据丢失或服务质量下降
  • 可扩展性更容易实现,无需复杂的负载平衡
  • 我们可以一次将消息发送到多个系统
  • 抽头模式 可能更容易调试

RESTful也没有单向请求的概念。 没有主体的POST越接近越好。 这是有问题的,因为许多业务案例自然都符合即兴即弃的语义。 当我发布域事件时,我不在乎响应,但是REST服务与HTTP协议紧密耦合。 但是,只有典型的请求-响应交互(例如通过ID检索用户)并不适合队列。 具有相关性ID的时间队列很尴尬,并引入了大量延迟。

没有标准,只有好的,有时是相互矛盾的做法。 我们甚至无法同意资源是单数还是复数,更不用说分页参数,错误处理,HATEOAS了。根据Richardson Maturity Model ,您会发现有人在争论您的服务是RESTful的。 缺乏标准意味着每个人都可以将其服务命名为RESTful。 这可能是Roy Fielding论文的生动示例,也可能是<form> POST处理程序–只要他们使用HTTP,它们就是REST。 这也意味着您现在永远不会如何与任何API正确交互。 您应使用哪些标头,如何解码响应,如何协商内容类型(标头?URL中的扩展名?)以及支持哪些类型。

RESTful服务具有处理向后兼容性的几种有缺陷的方式:

  • 仅添加字段,从不删除或更改。 我目睹了这样的情况,有人在一个碰巧被直接编码为JSON的对象中修复了一个无辜的错字。 这使另一个系统崩溃
  • 具有版本控制的内容类型–麻烦,需要维护多个版本
  • 如果资源已重命名,则HTTP重定向–仅在客户端具有足够的RESTful能力时才起作用,从而完全避免了硬编码的URL

上面的每种技术都有其自身的问题,RESTful服务根本不是旨在发展的。

在通过HTTP又称为REST嬉皮风格的JSON跳转到JSON之前,我希望您问自己几个问题:

  • 性能是一个问题吗? 然后选择更紧凑的格式,不需要昂贵的压缩
  • 您真的需要阻止请求-响应吗? 如果没有,请考虑消息队列或存储,例如Kafka
  • 您正在进行连续部署还是自动扩展? 然后选择不临时耦合客户端和服务器且无连接的技术,请参见上文
  • 您的交互是否复杂,或者您正在从模块中提取现有的API /接口到分布式服务? 然后选择更接近经典RPC的技术
  • 您是否需要一次语义 ? 如果是这样,对您没有任何帮助,对不起

PS:强制性附录: “被认为有害”的论文被认为有害 。

翻译自: https://www.javacodegeeks.com/2015/07/restful-considered-harmful.html

restful

小讯
上一篇 2025-04-16 16:36
下一篇 2025-05-26 14:56

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/137683.html