服务化改造实践 | 如何在 Dubbo 中支持 REST

本文介绍了REST的概念,它是Roy Thomas Fielding在2000年的博士论文中提出的一种互联网软件架构风格。RESTful架构强调资源的唯一标识、标准访问方式和多种表现形式。文章详细讲解了如何在Dubbo中实现REST支持,包括背景、基本用法和进阶技巧,如使用RESTEasy、配置REST服务、通过HTTP协议暴露服务等。此外,还探讨了如何在Dubbo中使用REST的不同方式,如Java配置、Tomcat服务器、外部Servlet容器以及集成Swagger UI进行文档和测试。
摘要由CSDN通过智能技术生成

什么是 REST

REST 是 Roy Thomas Fielding [[1]](#fn1) 在 2000 年他的博士论文 [[2]](#fn2) “架构风格以及基于网络的软件架构设计” 中提出来的一个概念。REST 是 RESTransfer 的缩写,翻译过来就是 “表现层状态转化”。REST 就是 Roy 在这篇论文中提出的面向互联网的软件所应当具备的架构风格。

按照 REpresentational State Transfer 的字面意思,可以把应用看成是一个虚拟的状态机,软件提供的不是服务而是一系列的资源统一的操作**来访问,而返回的结果代表了资源状态的一次跃迁。REST 是一种架构风格,如果一个软件架构符合 REST 风格,就可以称之为 RESTful 架构。这个架构应当具备以下一些设计上的约束:资源具有唯一标示、资源之间有关联关系、使用标准的方式来访问、资源有多种表现形式、无状态交互。

举例来说,一个简单的静态 HTML 页面的网站就很好的符合了 RESTful 架构风格。访问 http://acme.com/accounts 返回一个包含所有账号的页面,选取其中一个链接 http://acme.com/accounts/1 又会返回包含用户 1 的详细信息。爬虫软件在这种场景下工作的很好,当知道了某个网站的首页地址后,可以自举发现这个网站上所有关联的网页。更重要的是,这种访问形式不依赖网站提供的任何客户端,而是仅仅通过 HTTP 标准的访问方式完成的。可以说,HTML 这种超媒体文档的组织形式就是资源的表现层状态迁移的一种形式。

对于一个提供服务的动态网站来说,可以按照类似的思路将其 RESTful 化:

其中的思路是利用 HTTP 协议的标准方法 POST、DELETE、PUT、GET 来表达对于一个资源的增删改查 (CRUD) 操作,利用 URL 来表示一个资源的唯一标识。对资源访问的错误码也复用 HTTP 协议的状态码。返回结果通常由 json 或 XML 来表示,如果其中包换了对关联资源的访问方式 (所谓的表现层状态迁移) ,这种类型的 RESTful 应用可以进一步的称之为 hypermedia as the engine of application state (HATEOAS) 应用 [[3]](#fn3)。

source: https://www.nginx.com/wp-content/uploads/2016/04/micro-image.png

这里需要注意的是,按照 Roy 的定义,RESTful 架构风格与 HTTP 协议并没有什么强关联关系。但是,基于 HTTP 的 RESTful 架构风格是实现起来最自然,也是目前使用最广泛的一种实现,我们称之为 RESTful HTTP。同样的,在下文中将会专注在 HTTP 的场景下介绍如何在 Dubbo 框架中将服务暴露成 Restful 架构。

在 Dubbo 中使用 REST

背景

随着微服务的流行以及多语言互操作诉求日益增多,在 Dubbo 中暴露 REST 服务变成了一个不容忽视的诉求。为了在 Dubbo 中暴露 REST 服务,通常有两种做法,一种是直接依赖 Sprng REST 或者其他 REST 框架来直接暴露,另一种是通过 Dubbo 框架内置的 REST 能力暴露。两种做法各有优缺点,主要体现在前者与微服务体系中的服务发现组件能够更好的工作,而后者可以无缝的享受到 Dubbo 体系中的服务发现以及服务治理的能力。本文关注的是如何使用后者来暴露 REST 服务。

自 2.6.0 开始,Dubbo 合并了当当网捐献的 DubboX [[4]](#fn4) 中的主要特性,其中就包括了基于 RESTeasy 3.0.19.Final 的 REST 支持,具备 JAXRS 2.0 规范中所有的能力。

基本用法

在以下的例子中,展示了如何通过最传统的 Spring XML 配置的方式来快速的暴露和调用一个 REST 服务。其中底层的 server 使用的是 netty,服务注册发现基于 Zookeeper。

注:本章节讨论的示例可以通过 https://github.com/beiwei30/dubbo-rest-samples/tree/master/basic 来获得

1. Maven 依赖

首先需要在项目中引入 dubbo all-in-one 的依赖以及 RESTEasy 相关的必要依赖。因为在本例中使用 Zookeeper 作为服务发现,还需要引入 Zookeeper client 相关的依赖。为了方便使用,第三方的依赖可以通过框架提供的 BOM 文件 dubbo-dependencies-bom 来引入。

<properties>
        <dubbo.version>2.6.5</dubbo.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo-dependencies-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>${dubbo.version}</version>
        </dependency>

        <!-- REST support dependencies -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-netty4</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson-provider</artifactId>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxb-provider</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>

        <!-- zookeeper client dependency -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
        </dependency>
    </dependencies>

2. 定义服务接口

定义一个服务接口 UserService,该接口提供两个功能,一个是获取指定 User 的详细信息,另一个是新注册一个用户。

@Path("users") // #1
@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) // #2
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
public interface UserService {
    @GET // #3
    @Path("{id: \\d+}")
    User getUser(@PathParam("id") Long id);

    @POST // #4
    @Path("register")
    Long registerUser(User user);
}

通过在接口上用 JaxRS 标准的 annotation 来修饰,我们规定了该服务在 REST 下的访问形式:

  1. @Path("users") 定义了 UserService 通过 '/users' 来访问
  2. 在类级别上定义 @Consumers 和 @Produces 来规定参数以及返回值的类型为 XML 和 JSON。在类级别上定义之后,就可以不用在方法级别上进一步定义了
  3. getUser 方法上通过 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值