第 4 章 定义 REST 服务

摘要

Apache Camel 支持多种定义 REST 服务的方法。特别是,Apache Camel 提供 REST DSL (域特定语言),它是一个简单但强大的 fluent API,它可以在任何 REST 组件上分层并提供与 Swagger 集成。

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:

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

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

Hello Garp

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

REST 包装程序层

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

REST DSL

REST DSL (在 camel-core中)是一个 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 实施相结合。

如果您没有显式配置 HTTP 传输组件,则 REST DSL 通过检查类路径上的可用组件来自动发现要使用的 HTTP 组件。REST DSL 会查找任何 HTTP 组件的默认名称,并使用找到的第一个名称。如果 classpath 中没有 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 分层。总之,JAX-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 集成。