使用 Apache Camel 創建 REST 服務


使用 Apache Camel 創建 REST 服務

讓我們使用 Camel 的 REST DSL 創建一個 REST 服務!請參閱使用 Apache Camel 和 Spring Boot 實現 REST API 的示例。

使用 Apache Camel 創建 REST 服務

您已經了解了Apache Camel 的一些基礎知識。您現在知道如何處理消息。偉大的!下一個是什么?

您可能想要開始使用 Web 服務。

因此,在本教程中,我將展示如何使用 Camel從應用程序公開 REST 端點

我將介紹您開始所需的依賴項和配置。最后,有一個示例供您參考,以便您了解如何使用 Apache Camel 和 Spring Boot 創建自己的 RESTful 服務。

如果您不熟悉 Apache Camel,那么我鼓勵您閱讀我的Apache Camel 教程的第一部分。

基礎知識

如何使用 Camel 創建 REST 服務?

您現在可能已經知道 Camel 是一個用於在不同系統之間進行集成的框架。它通常不會自己做一些事情,而是創建和配置一些實際完成工作的東西(例如一個組件)。

在 Camel 中創建 REST 服務遵循幾乎相同的模式。為 Camel 編寫一些說明,它將使用一堆其他組件為您公開您的 REST 服務。您只需要准確選擇您希望服務實現的方式,Camel 將負責配置。

這意味着使用 Camel 創建 REST 服務有無數種不同的方式。因此,我不會涵蓋每一種不同的方法,而只是簡要提及您可以在 Apache Camel 中使用 REST 服務的主要方法。你可以:

  • 使用 Camel 支持的組件之一公開一個 REST 服務:您使用 Camel 的 REST DSL 或 REST 組件定義您的 REST 服務操作,並選擇一個將被配置為實現您的服務的組件。然后,Camel 將使用該信息來引導組件、創建您的服務及其操作、將其部署到 Web 服務器(如 Jetty 或 Undertow)中,並為您生成 Swagger/OpenAPI 文檔。(這非常簡單,這就是我將在本教程中介紹的方式。)

  • 使用 Camel 來引導使用 JAX-RS 的服務: Camel 與 Apache CXF 緊密集成,這是 Java 的Web 服務JAX-RS 規范的一種實現。因此,如果您正在考慮使用 JAX-RS 標准來定義您的 REST 服務,那么您可以使用 Camel 使用 CXF 為您引導您的服務。查看CXFRS 組件以獲取更多信息。

  • 使用 Camel 為現有的 REST 服務提供業務邏輯:如果您已經在應用程序的其他地方公開了 REST 服務——例如使用JAX-RS或 Spring Rest——那么您可以使用 Camel 來實現實際的業務邏輯,如果你喜歡。

    例如,您可能已經編寫了一個包含使用javax.ws.rs注釋(@Path@GET@POST等)注釋的方法的服務類,並且已經配置了您的實現(例如 CXF、Jersey 或 Resteasy)。如果是這樣,那么在您的服務方法中,您可以使用 Camel 的 Java API(ProducerTemplate等)將消息發送到 Camel 路由,然后使用來自 Camel 的響應傳遞回您的使用者。

那么有沒有“最好的方法”呢?

嗯,不。:)

但在本教程中,我將向您展示我的首選方法。我們將使用 Camel 的 REST DSL 來配置服務並將其部署到嵌入式 Web 服務器中,該服務器在 Spring Boot 中運行。

使用 REST DSL 創建 REST 服務

那么如何在 Camel 中定義 REST 服務呢?最好的方法是使用 REST DSL。

REST DSL 是 Camel 現有路由構建語法的擴展,但專門用於描述 REST 服務。編寫和配置很容易。

在幕后,Camel 使用您的 REST DSL 代碼來配置實際提供REST 服務的底層組件。您現在不需要擔心這些細節,因為 Camel 會為您設置大部分默認值。

REST DSL 可以輕松定義 REST 服務,而無需了解太多底層細節或任何復雜的布線。

在非常高的層次上,當使用 Camel 創建 REST 服務時,我們需要做以下事情:

  1. 聲明我們的 RESTful 服務的端點和操作

  2. 選擇哪個組件將實現該服務(有關支持的組件列表,請參見下文)

  3. 添加代碼以使用參數

  4. 添加配置以獲取 Camel 以幫助我們處理 JSON 或 XML。

定義endpoints端點和操作

為了定義我們服務的操作,我們可以使用 REST DSL 語法。Camel在 Camel 2.14 中引入了REST DSL。REST DSL 基本上是用於定義 REST 服務的 Camel 語法。

看起來有點像普通的Camel route…… 除了它以rest(). 定義您使用的服務,rest(...)然后是您的操作,其采用 HTTP 動詞的形式,例如.get().post()等。

在 Java DSL 中,它看起來像這樣:

rest("/api/customers")
    .get()
        .route()
        .to("direct:getCustomers")
    .post()
        .route()
        .to("file:output/customers");

在 Camel 的 XML DSL 中:

<rest path="/api/customers">
    <get>
        <route>
            <to uri="direct:getCustomers"/>
        </route>
    </get>
    <post>
        <route>
            <to uri="file:output/customers"/>
        </route>
    </post>
</rest>

REST 消費者還是 REST 生產者?當 Camel 公開或提供 REST 服務時,Camel 使用術語consumer,因為 Camel 正在通過 REST 消費提供給它的數據。另一方面,REST生產者是 Camel 消費或調用外部 REST 服務的地方。

配置實現

現在我們需要設置一些關於服務本身的信息。我們需要選擇哪個組件將實現服務,並設置任何屬性,如主機名端口

第一件事是選擇 Camel 應該引導哪個組件來實現您的 REST 服務。在這里,您可以選擇:

  • servlet

  • spark-rest

  • netty-http

  • jetty

選擇哪個組件完全取決於您,但是對於 Spring Boot 應用程序,我會選擇servlet,因為您已經擁有一個 Camel 可以用於 servlet (Tomcat) 的嵌入式 Web 服務器。

然后您可以在restConfiguration()塊中設置此配置,如下所示:

// 定義實現組件 - 並接受默認主機和端口
restConfiguration().component("servlet");
​
// 定義組件和主機名和端口
restConfiguration().component("servlet")
    .host("localhost").port(8080);

使用參數

您的 REST API 可能需要接受來自使用者的參數。無論您是在正文、URL 還是在查詢字符串中使用參數,都可以輕松做到這一點。

POST 正文

像POST這樣的操作很容易。請求的正文將存儲在 Camel Exchange Body 中。所以你可以像這樣訪問它:

rest("/customers")
    .post().log("The body is ${body}!");

網址參數

當您需要從 URL 中讀取參數(例如客戶 ID 或產品 ID)時,您需要:

  • 在您的操作的 URI 中定義一個占位符,例如/customers/{id}

  • 稍后獲取您的輸入,使用同名的Header - 例如${header.id}

這是一個示例 - 一個采用客戶 ID 的 REST 刪除操作。該參數{id}在聲明uri-如/customers/12345。然后可以使用${header.id}以下方法檢索它:

Java DSL

rest("/api/apartments")
    .get("/search?country={country}")
    .to("bean:searchBean?method=byCountry(${header.country})");

XML DSL

<rest path="/api/apartments">
    <get uri="/search?country={country}">
        <to uri="bean:searchBean?method=byCountry(${header.country})"/>
    </get>
</rest>

設置 JSON 到 POJO 轉換

最后,我們需要弄清楚我們想要對我們的請求和響應消息做什么。如果您正在接收或發送 JSON,那么 Camel 如何提供幫助?

您可以手動編寫自己的 JSON 字符串,但它非常麻煩,而且編寫一大堆字符串連接也沒什么樂趣!

答案是對您的請求和響應類型使用 POJO。是的,Java 對象。當您將 POJO 用於輸入和輸出消息時,Camel 可以為您的 REST 服務使用者輕松地將這些消息與 JSON 進行相互轉換。如果 Jackson 在類路徑上,Camel 能夠做到這一點。

這是一個示例供您查看。首先,這是我編寫的一個名為ResponseType的類,它對來自我的 RESTful API 的響應進行建模。它包含一個字段,message

public class ResponseType {
​
    private String message;
​
    public ResponseType(String message) {
        this.message = message;
    }
​
    public String getMessage() { }
        return message;
    }
​
    public void setMessage(String message) {
        this.message = message;
    }
}

為了讓 Camel 自動將其從我的 REST 服務編組為 JSON,我確保.outType()設置了它,並且它引用了我的自定義ResponseType類。這告訴 Camel 它應該期望將類型為ResponseType的消息返回給消費者:

rest().path("/my-api").....
    .get()
        .outType(ResponseType.class)
        .to("bean:helloBean"); // this sends the Body to the bean

由於我的 REST 操作的業務邏輯是在 Java bean 中實現的,我只需要確保我的業務邏輯方法返回一個類型為ResponseType的對象:

public class HelloBean {
    public ResponseType sayHello() {
        return new ResponseType("Hello, world!");
    }
}

最后,我需要給 Camel 一個提示,將 JSON 綁定到 Java 對象。這是使用bindingMode配置完成的,我添加到restConfiguration塊中:

restConfiguration()
    .component("servlet")
    .bindingMode(RestBindingMode.auto);

或者,如果您願意,可以在 XML DSL 中:

<restConfiguration component="servlet" bindingMode="auto"/>

現在,當我使用curl測試服務時,HelloBean將返回一個ResponseType對象。Camel 將使用 Jackson 為我自動將其編組為 JSON - 請注意我如何獲得包含一個字段 的 JSON 對象message,這就像我上面的示例 POJO:

$ curl http://localhost:8080/services/my-api
{"message":"Hello, world!"}

示例 - 使用 REST DSL 在 Camel 中創建RESTful 服務

現在我們知道使用 Camel 創建 RESTful 服務需要什么——一個將實現服務的組件,以及一些 REST DSL 糖來配置它。這個例子將:

  • 使用servlet組件托管 RESTful 服務

  • 在默認的 Spring Boot Web 端口上運行,即 8080

  • 在 JSON 和 Java 對象之間自動轉換,這樣我們就不必自己搞砸了

要創建服務,請按照下列步驟操作:

  1. 創建一個新的 Camel Spring Boot 項目

  2. 在您的 Maven POM 中,添加camel-servlet-starter為依賴項。這將允許 Camel 將我們的服務部署到嵌入式 Tomcat 容器中:

     <dependency>
     <groupId>org.apache.camel.springboot</groupId>
     <artifactId>camel-servlet-starter</artifactId>
     </dependency>
  3. 添加camel-jackson-starter為依賴項。這將允許 Camel 編組到/從 JSON:

     <dependency>
     <groupId>org.apache.camel.springboot</groupId>
     <artifactId>camel-jackson-starter</artifactId>
     </dependency>
  4. RouteBuilder新項目的 中,添加一個restConfiguration()元素。

    這將初始化將提供REST 服務的組件。在這個例子中,我們為此使用了Servlet組件。

    在為服務定義任何操作之前,我們首先執行此操作:

     public void configure() throws Exception {
     restConfiguration()
           .component("servlet")
           .bindingMode(RestBindingMode.auto);
     }
  5. 定義一個 REST 端點,並為您的每個操作(GET、POST 等)添加框架。

    首先,使用服務的路徑 (URI)定義 REST 端點rest。然后附加您的每個操作- 這些是您的 HTTP 動詞。

    REST 動詞/操作的語法看起來就像熟悉的 Camel 路由。但是,from我們使用您要使用的HTTP 動詞(例如getpost和 )開始每個操作,而不是delete

    像這樣做:

    語言語言

     rest("/api/customers")
         .get().route().to("...")
         .post().route().to("...")
         .delete().route().to("...");

    XML DSL

    <rest path="/api/customers">
       <get>
         <route>
             <to uri="..."/>
         </route>
       </get>
       <post>
         <route>
             <to uri="..."/>
         </route>
       </post>
     </rest>

    該在什么時候使用哪個 HTTP 動詞上?看到這篇文章的結尾,我寫了一個厚顏無恥的小備忘單。

  6. 現在為您的 REST 操作構建您的駱駝路線!以下是已填寫的 REST 服務示例:

    Java DSL

     rest("/customers")
     .get().route().to("bean:customerService?method=listCustomers")
     .post().route().to("jms:queue:CUSTOMERS");

    XML DSL

     <rest path="/customers">
     <get>
       <route>
           <to uri="bean:customerService?method=listCustomers"/>
       </route>
     </get>
     <post>
       <route>
           <to uri="direct:post"/>
       </route>
     </post>
     </rest>

    正如你所看到的,GET操作通過一個beancustomerService傳遞服務的請求。但是POST操作將請求傳遞給一個直接分量direct:post

  7. 要添加對自動將請求和響應轉換為 JSON 的支持,請定義代表您的請求和響應消息的 POJO,例如:

     public class CreateCustomerResponse {
     private String result;
     // Add some getters and setters here...
     }

    現在,聲明您的請求和響應類型,以便 Camel 知道如何將它們編組到 JSON 或從 JSON 編組:

     rest()
       .post()
         .route()
         .type(Customer.class)
         .outType(CreateCustomerResponse.class)
         .to("direct:post");

    並確保您已在REST 配置中設置綁定模式

     restConfiguration()
         .component("servlet")
         .bindingMode(RestBindingMode.auto);
    就是這樣!現在繼續使用您需要的盡可能多的端點和操作來構建您的 REST API。

只是想看看完整的、有效的例子?單擊下面的按鈕查看完整示例:

獲取示例代碼 在 GitHub 上

HTTP 動詞 何時使用 例子
GET 獲取/檢索實體 GET /customers/:id
POST 創建一個新實體 POST /customers
PUT 更新現有實體 PUT /customers/:id/tags
DELETE 刪除現有實體 DELETE /customers/:id


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM