第 4 章 定义 REST 服务

摘要

Apache Camel 支持多种方法来定义 REST 服务。特别是,Apache Camel 提供 REST DSL(Domain Specific Language),它是一种简单但强大的流畅 API,可以在任何 REST 组件上分层并提供与 OpenAPI 集成。

4.1. Camel 中的 REST 概述

概述

Apache Camel 提供了很多不同的方法和组件,用于在 Camel 应用程序中定义 REST 服务。本节概述了这些不同方法和组件,以便您可以决定哪些实施和 API 最适合您的要求。

什么是 REST?

Representational State Transfer (REST)是一个分布式应用程序的架构,它仅利用 HTTP 传输数据的中心,仅使用四个基本的 HTTP 动词: GETPOSTPUTDELETE

与 SOAP 等协议不同,它把 HTTP 视为 SOAP 消息的传输协议,REST 架构直接利用 HTTP。关键洞察是,HTTP 协议 本身 由几个简单惯例增强,它非常适合充当分布式应用程序的框架。

REST 调用示例

因为 REST 架构围绕标准 HTTP 动词构建,因此在很多情况下,您可以使用常规浏览器作为 REST 客户端。例如,若要调用在主机和端口 localhost:9091 上运行的简单 Hello World REST 服务,您可以在浏览器中导航到类似于以下 URL 的 URL:

http://localhost:9091/say/hello/Garp

Hello World REST 服务可能会返回响应字符串,例如:

Hello Garp

其显示在浏览器窗口中。您可以使用标准浏览器(或 curl 命令行实用程序)调用 REST 服务的简易性,是 REST 协议快速获得流行的原因之一。

REST 打包程序层

以下 REST 打包程序层提供了定义 REST 服务的简化语法,并可在不同 REST 实现之上分层:

REST DSL

REST DSL(在 camelcore中)是一个 facade 或 wrapper 层,它为定义 REST 服务提供了一个简化的构建器 API。REST DSL 本身不 提供 REST 实现:它必须与底层 REST 实现合并。例如,以下 Java 代码演示了如何使用 REST DSL 定义一个简单的 Hello World 服务:

rest("/say")
    .get("/hello/{name}").route().transform().simple("Hello ${header.name}");

如需了解更多详细信息,请参阅 第 4.2 节 “使用 REST DSL 定义服务”

REST 组件

Rest 组件(在 camel-core中)是一个打包程序层,可让您使用 URI 语法定义 REST 服务。与 REST DSL 一样,Rest( Rest)组件本身 不提供 REST 实现。它必须与底层 REST 实现相结合。

如果您没有显式配置 HTTP 传输组件,则 REST DSL 会自动发现通过检查类路径上的可用组件来使用的 HTTP 组件。REST DSL 查找任何 HTTP 组件的默认名称,并使用它找到的第一个名称。如果类路径中没有 HTTP 组件,并且您没有显式配置 HTTP 传输,则默认 HTTP 组件为 camel-http

注意

自动发现要使用哪些 HTTP 组件的功能是 Camel 2.18 中的新功能。Camel 2.17 中不提供它。

以下 Java 代码演示了如何使用 camel-rest 组件定义一个简单的 Hello World 服务:

from("rest:get:say:/hello/{name}").transform().simple("Hello ${header.name}");

REST 实现

Apache Camel 通过以下组件提供多个不同的 REST 实现:

spark-Rest 组件

Spark-Rest 组件(在 camel-spark-rest)是一个 REST 实现,可让您使用 URI 语法定义 REST 服务。Spark 框架本身是一个 Java API,它基于 Sinatra 框架(一个 Python API)。例如,以下 Java 代码演示了如何使用 Spark-Rest 组件定义一个简单的 Hello World 服务:

from("spark-rest:get:/say/hello/:name").transform().simple("Hello ${header.name}");

请注意,与 Rest 组件不同,URI 中的变量语法为 :name,而不是 {name}

注意

Spark-Rest 组件需要 Java 8。

Restlet 组件

Restlet 组件(在 camel-restlet)是一个 REST 实现,在原则上可以进行分层,但此组件仅针对 HTTP 协议进行测试。此组件还提供与 Restlet Framework 集成,它是 Java 中开发 REST 服务的一种商业框架。例如,以下 Java 代码演示了如何使用 Restlet 组件定义一个简单的 Hello World 服务:

from("restlet:http://0.0.0.0:9091/say/hello/{name}?restletMethod=get")
    .transform().simple("Hello ${header.name}");

如需了解更多详细信息,请参阅 Apache Camel 组件参考指南 中的 Restlet

servlet 组件

Servlet 组件(在 camel-servlet中)是一个组件,它将 Java servlet 绑定到 Camel 路由。换而言之,Servlet 组件可让您打包和部署 Camel 路由,就像它是标准的 Java servlet。因此,当您需要在 servlet 容器中部署 Camel 路由(例如,到 Apache Tomcat HTTP 服务器或 JBoss Enterprise Application Platform 容器中)中,Servlet 组件特别有用。

但是,它本身的 Servlet 组件不提供任何便捷的 REST API 来定义 REST 服务。因此,最简单的使用 Servlet 组件是将其与 REST DSL 合并,以便您可以用用户友好的 API 定义 REST 服务。

如需了解更多详细信息,请参阅 Apache Camel 组件参考指南 中的 Servlet

JAX-RS REST 实施

JAX-RS (RESTful Web 服务的 Java API)是一个将 REST 请求绑定到 Java 对象的框架,其中 Java 类必须使用 JAX-RS 注释进行解码,以定义绑定。JAX-RS 框架相对成熟,为开发 REST 服务提供了复杂的框架,但它在编程上也比较复杂。

JAX-RS 与 Apache Camel 集成由 CXFRS 组件实施,该组件通过 Apache CXF 进行分层。简而言之,CIBian-RS 使用以下注释将 REST 请求绑定到 Java 类(其中,这仅是许多可用注释的不完整示例):

@Path
标注可以映射至 Java 类的上下文路径,或者将子路径映射到特定的 Java 方法。
@GET, @POST, @PUT, @DELETE
将 HTTP 方法映射到 Java 方法的标注。
@PathParam
将 URI 参数映射到 Java 方法参数的注解,或者将 URI 参数注入到字段中。
@QueryParam
注释,可将查询参数映射到 Java 方法参数,或者将查询参数注入字段。

REST 请求或 REST 响应的正文通常应采用 JAXB(XML)数据格式。但 Apache CXF 还支持 JSON 格式转换为 JAXB 格式,以便也可以解析 JSON 消息。

如需了解更多详细信息,请参阅 Apache Camel 组件参考指南 和 Apache CXF 开发指南中的 CXFRS

注意

CXFRS 组件 没有与 REST DSL 集成。