JAVA削足适履适应RESTful设计

没有人可以否认这些年来Java在软件开发领域的积极影响。或者说,对众多的开发者和应用程序而言,Java和JVM仍然是占统治地位的通用解决方案。无论是CORBA、SOA、REST还是 Web服务,Java都能够支持。对于无处不在的Java和REST,二者结合的标准方法的出现(即已经在EE6中介绍的JAX-RS)只是时间问题。目前已经有很多JAX-RS的实现,包括Jersey(参考实现)和RESTeasy,其中RESTeasy已经有广泛的应用。

过去几年,虽然对JAX-RS有一些争论,特别是围绕它是否支持RESTful风格的设计。其中的一些问题,已经被JAX-RS 2.0技术委员会考虑,但是在最近的JavaOne 2012大会上,仍然有一些关于标准的提问。11月早些时候,Zapthink的一篇论文也加入了这一论战,再次质疑Java甚至JAX-RS是否适合于构建RESTful应用程序。

Java Community Process(JCP)的不断努力,已增强了Java生态系统的能力,以应对范围广泛的新问题和新情况。他们不断对Java投入工作,为满足未来几年的需求。但话又说回来,也许不能。Java EE的重量级的模型-视图-控制器(MVC)架构,或者Java简单的面向对象的环境,可能无法支持其它架构方法。

当然,也有些与Java无关的蓬勃发展的JVM社区,比如JRuby、Clojure、Scala 和 JavaScript,你不需要为了使用JavaEE内部的很多能力(比如事务和安全等)而去学习Java EE。这些语言本身有一些构建RESTful服务的方法。然而,Zapthink认为, Java对JAX-RS规范的支持特别差劲。

不幸的是,JAX-RS是一个削足适履的典型例子。它为Java增加了一些RESTful的功能,但是,却在每一步中又屏蔽了RESTful架构风格。例如:HATEOAS约束。JAX-RS 1.1一点儿都不支持超媒体。这从本质上说,这意味着我们必须利用Java的核心能力模拟实现HATEOAS特性。为了使JAX-RS完全支持RESTful,我们必须设计满足所有REST体系结构约束的应用程序,以补偿那些在开发期间未得到支持的特性。JAX-RS 1.1为REST架构约束提供了丰富的支持,但却丢弃了HATEOAS。

缺少对超媒体的支持是JAX-RS技术委员会试图在最新的版本中解决的问题之一。但是,它远远不能满足该文所关注的:JAX-RS严重依赖Java注解,但是没有注解来阐述超链接,这导致产生了一些临时的方法,可它们却应该是标准的一部分。

文章还指出,一些其他领域,即便新版本标准中也未提及,尽管它们是否应该属于JAX-RS或其他标准尚无定论。

同样重要的是,只要有可能,就要将自定义的媒体类型标准化。而且用户还必须选择要使用标准媒体类型及自定义媒体类型。此外,服务可发现性的设计原则以及基于REST HATEOAS设计约束,要求在适当的地方进行超媒体控制。可发现性使该协议变的自描述。

最后一点是强加于JAX-RS的一个重要约束。ZapThink认为,它妨碍了JAX-RS和Java对RESTful服务的适应。正如Arun Gupta在讨论JAX-RS 2.0的早期草案时所解释的,有两种类型的超媒体链接。

RESTful的主要原则的之一是链接资源。其中之一是结构性链接,它用来避免发送完整的资源的表述和避免启用延迟加载。客户可以根据这一类型的链接来检索他们所需要的“碎片”。过渡性链接,用来更新资源状态,通常是用一个“rel”属性标识。结构性链接通常在实体内,过渡性连接可能在链接的头部或者实体内。

然而,尽管JAX-RS2.0只支持过渡链接的事实,ZapThink认为,二者对RESTful服务都不是绝对必须的。

如果我们简单地定义一个Java对象,并把它转换成超媒体,就会得到一个链接,那么该链接则描述了所有方法相关的对象实例,产生巨大的、复杂的表述。相反,JAX-RS鼓励过渡链接,使得客户端能逐步得到相关潜在的综合信息。但是,如果起先我们没有被Java对象的结构所限制,我们就永远不会为过渡链接和结构链接操心。相反,我们需要设计超媒体应用程序使之支持可发现性。换句话说,一个重要的Java模式成了超媒体反模式。

除了上述事实,在构建RESTful服务方面,JAX-RS2.0可能仍然存在不足。作者的结论是,你需要记住的是,REST并不是一种实现,而是一种架构方法。

在开发JAX-RS并考虑REST时,人们常常感到困惑。JAX-RS 不是为REST设计的;否则, JAX-RS应该能很好的支持REST风格的设计。此外,使用JAX-RS API并不会产生完全RESTful的服务,除非事先已完成合适的REST风格设计。该设计必须确保你已经满足所有RESTful架构约束。

当然,也有人此前讨论过这可能REST 或者SOA有关。但有,是否存在一些与JAX-RS或用Java构建RESTful服务相关的根本问题,如Zapthink的文章所述?文章的其中一个评论者问到:

非常严肃的说,当用RESTful方法构建系统时,你建议用什么语言替代Java?我知道,Java正在变得“老迈”,但我坚信强类型化和Java体现的其他编程实践等好处。你认为Scala(下下一代Java)会更合适吗?如果不是Scala,那又是什么?

作者回应:

我不会简单地支持任何一种语言,因为我确信,任何编程语言都是有价值的,只要它为实现REST兼容的架构提供足够的支持。当然,架构对语言的选择也会产生一定影响。但更重要的是,专注于应用程序的设计,使之符合REST设计约束。

仍然留下一个问题:特别是与其他语言相比,Java是削足适履以适应Restful设计了吗?

查看英文原文:Shoehorning Java into RESTful Design

感谢马国耀对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至[email protected]。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

你可能感兴趣的:(JAVA削足适履适应RESTful设计)