知識庫 / REST RSS 訂閱

LinkRest 指南

REST
HongKong
5
03:54 AM · Dec 06 ,2025

1. 概述

LinkRest 是一個開源框架,用於構建基於數據的 REST Web 服務。它基於 JAX-RSApache Cayenne ORM,並使用 HTTP/JSON 消息協議。

基本上,這個框架旨在提供一種便捷的方式來將我們的數據存儲暴露到 Web 上。

在後續部分,我們將探討如何使用 LinkRest 構建一個 REST Web 服務,以訪問數據模型。

2. Maven 依賴項

為了開始使用該庫,首先我們需要添加 link-rest 依賴項:

<dependency>
    <groupId>com.nhl.link.rest</groupId>
    <artifactId>link-rest</artifactId>
    <version>2.9</version>
</dependency>

這也會引入 cayenne-server 構件。

此外,我們還將使用 Jersey 作為 JAX-RS 實現,因此我們需要添加 jersey-container-servlet 依賴項,以及 jersey-media-moxy 用於序列化 JSON 響應:

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.25.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <version>2.25.1</version>
</dependency>

為了我們的示例,我們將使用內存中的 H2數據庫,因為它更容易設置;因此,我們還將添加 h2

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.196</version>
</dependency>

3. Cayenne 數據模型

我們將使用的數據模型包含一個 部門 (Department) 和一個 員工 (Employee) 實體,它們代表着一對多關係:

正如前面提到的,LinkRest 與使用 Apache Cayenne ORM 生成的數據對象一起工作。 使用 Cayenne 不是本文的主要內容,有關更多信息,請參閲 Apache Cayenne 文檔

我們將保存 Cayenne 項目到一個名為 cayenne-linkrest-project.xml 的文件中。

運行 cayenne-maven-plugin 後,它將生成兩個 _Department_Employee 抽象類,這些類將繼承 CayenneDataObject 類,以及由此派生的兩個具體類,DepartmentEmployee

這些後來的類是我們可自定義和使用與 LinkRest 配合使用的類。

4. LinkRest 應用程序啓動

在下一部分,我們將編寫和測試 REST 端點,因此為了能夠運行它們,我們需要設置我們的運行時環境。

由於我們使用 Jersey 作為 JAX-RS 實現,我們將添加一個擴展 ResourceConfig 的類,並指定包含我們定義 REST 端點類的包:

@ApplicationPath("/linkrest")
public class LinkRestApplication extends ResourceConfig {

    public LinkRestApplication() {
        packages("com.baeldung.linkrest.apis");
        
        // load linkrest runtime
    }
}

在同一個構造函數中,我們需要構建並註冊 LinkRestRuntimeJersey 容器。該類基於首先加載 CayenneRuntime

ServerRuntime cayenneRuntime = ServerRuntime.builder()
  .addConfig("cayenne-linkrest-project.xml")
  .build();
LinkRestRuntime lrRuntime = LinkRestBuilder.build(cayenneRuntime);
super.register(lrRuntime);

最後,我們需要將該類添加到web.xml中:

<servlet>
    <servlet-name>linkrest</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.baeldung.LinkRestApplication</param-value>
        </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>linkrest</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

5. REST 資源

現在我們已經定義了模型類,就可以開始編寫 REST 資源。

REST 端點使用標準的 JAX-RS 註解創建,響應構建則使用 LinkRest 類。

我們的示例將包含編寫一系列 CRUD 端點,這些端點通過不同的 HTTP 方法訪問 /department URL:

首先,讓我們創建一個 DepartmentResource 類,該類映射到 /department

@Path("department")
@Produces(MediaType.APPLICATION_JSON)
public class DepartmentResource {

    @Context
    private Configuration config;
    
    // ...
}

LinkRest 類需要 JAX-RS Configuration 類的實例,該實例通過 Context 註解進行注入,該註解也由 JAX-RS 提供。

接下來,我們繼續編寫訪問 Department 對象的所有端點。

5.1. 使用 POST 創建實體

要創建實體,<em/>LinkRest</em/> 類提供 <em/>create()</em/> 方法,該方法返回一個UpdateBuilder</em/> 對象:

@POST
public SimpleResponse create(String data) {
    return LinkRest.create(Department.class, config).sync(data);
}

數據參數可以是單個表示 部門 的 JSON 對象,也可以是對象數組。該參數通過 sync() 方法發送到 UpdateBuilder,用於創建和插入一個或多個對象到數據庫中,方法返回一個 SimpleResponse

該庫定義了 3 種額外的響應格式:

  • DataResponse<T> – 一個表示 T 對象的集合的響應
  • MetadataResponse<T> – 包含關於類型的元數據信息
  • SimpleResponse – 一個包含兩個 successmessage 屬性的對象

接下來,我們使用 curlDepartment 記錄添加到數據庫中:

curl -i -X POST -H "Content-Type:application/json" 
  -d "{"name":"IT"}" http://localhost:8080/linkrest/department

因此,命令返回狀態碼 201 Created 以及 success 屬性。

{"success":true}

我們還可以通過發送 JSON 數組創建多個對象:

curl -i -X POST -H "Content-Type:application/json" 
  -d "[{"name":"HR"},{"name":"Marketing"}]" 
  http://localhost:8080/linkrest/department

5.2. 使用 GET 讀取實體

主要用於查詢對象的代碼是 <em >select()</em> 方法,來自 <em >LinkRest</em> 類。它返回一個 <em >SelectBuilder</em> 對象,我們可以使用它來鏈接額外的查詢或過濾方法。

讓我們在 <em >DepartmentResource</em> 類中創建一個端點,以返回數據庫中的所有 <em >Department</em> 對象:

@GET
public DataResponse<Department> getAll(@Context UriInfo uriInfo) {
    return LinkRest.select(Department.class, config).uri(uriInfo).get();
}

uri() 調用設置 SelectBuilder 的請求信息,而 get() 則返回一個包含 Departments 的集合,並將其包裝為 DataResponse<Department> 對象。

下面我們來看一下在通過此端點添加的部門:

curl -i -X GET http://localhost:8080/linkrest/department

響應形式為包含 data 數組和 total 屬性的 JSON 對象:

{"data":[
  {"id":200,"name":"IT"},
  {"id":201,"name":"Marketing"},
  {"id":202,"name":"HR"}
], 
"total":3}

或者,要檢索對象集合,可以使用getOne()方法,代替get()方法。

讓我們添加一個映射到/department/{departmentId}的端點,該端點返回具有給定 ID 的對象。為此,我們將使用byId()方法過濾記錄:

@GET
@Path("{id}")
public DataResponse<Department> getOne(@PathParam("id") int id, 
  @Context UriInfo uriInfo) {
    return LinkRest.select(Department.class, config)
      .byId(id).uri(uriInfo).getOne();
}

然後,我們可以向這個 URL 發送一個 GET 請求:

curl -i -X GET http://localhost:8080/linkrest/department/200

結果是一個包含一個元素的 <em >數據</em> 數組:

{"data":[{"id":200,"name":"IT"}],"total":1}

5.3. 使用 PUT 更新實體

要更新記錄,可以使用 <em >update()</em><em >createOrUpdate()</em> 方法。 後者如果記錄存在,則會更新它們;如果不存在,則會創建它們。

@PUT
public SimpleResponse createOrUpdate(String data) {
    return LinkRest.createOrUpdate(Department.class, config).sync(data);
}

類似於之前的部分,data 參數可以是單個對象或對象數組。

讓我們更新之前添加的一個部門:

curl -i -X PUT -H "Content-Type:application/json" 
  -d "{"id":202,"name":"Human Resources"}" 
  http://localhost:8080/linkrest/department

這段操作返回一個包含成功或錯誤消息的 JSON 對象。之後,我們可以驗證 ID 為 202 的部門名稱是否已更改。

curl -i -X GET http://localhost:8080/linkrest/department/202

當然,這一個命令確實返回了帶有新名稱的對象:

{"data":[
  {"id":202,"name":"Human Resources"}
],
"total":1}

5.4. 使用 DELETE 操作刪除實體

要刪除一個對象,我們可以調用 delete() 方法,它會創建一個 DeleteBuilder 對象,然後使用 id() 方法指定要刪除的對象的主鍵:

@DELETE
@Path("{id}")
public SimpleResponse delete(@PathParam("id") int id) {
    return LinkRest.delete(Department.class, config).id(id).delete();
}

然後我們可以使用 curl 調用這個端點:

curl -i -X DELETE http://localhost:8080/linkrest/department/202

5.5. 處理實體間的關係

LinkRest 同樣包含方法,簡化了對象間關係的處理。

由於部門員工之間存在一對多關係,我們將添加一個 /department/{departmentId}/employees 端點,訪問一個 EmployeeSubResource 類:

@Path("{id}/employees")
public EmployeeSubResource getEmployees(
  @PathParam("id") int id, @Context UriInfo uriInfo) {
    return new EmployeeSubResource(id);
}

EmployeeSubResource 類對應一個部門,因此它將具有一個設置部門 ID 的構造函數,以及Configuration 實例:

@Produces(MediaType.APPLICATION_JSON)
public class EmployeeSubResource {
    private Configuration config;

    private int departmentId;

    public EmployeeSubResource(int departmentId, Configuration configuration) {
        this.departmentId = departmentId;
        this.config = config;
    }

    public EmployeeSubResource() {
    }
}

請注意,為了使對象能夠作為 JSON 對象序列化,需要提供默認構造函數。

接下來,讓我們定義一個從部門檢索所有員工的端點:

@GET
public DataResponse<Employee> getAll(@Context UriInfo uriInfo) {
    return LinkRest.select(Employee.class, config)
      .toManyParent(Department.class, departmentId, Department.EMPLOYEES)
      .uri(uriInfo).get();
}

在本示例中,我們使用了 toManyParent() 方法,該方法位於 SelectBuilder 中,用於查詢具有指定父級的對象。

POST、PUT、DELETE 方法的端點可以以類似的方式創建。

要將員工添加到部門,我們可以通過使用帶有 POST 方法的 departments/{departmentId}/employees 端點來實現:

curl -i -X POST -H "Content-Type:application/json" 
  -d "{"name":"John"}" http://localhost:8080/linkrest/department/200/employees

然後,我們向查看部門員工發送一個 GET 請求:

curl -i -X GET "http://localhost:8080/linkrest/department/200/employees

這會返回一個包含數據的 JSON 對象:

{"data":[{"id":200,"name":"John"}],"total":1}

6. 使用請求參數自定義響應

LinkRest 提供了一種便捷的方式,通過向請求添加特定參數來自定義響應。這些參數可用於過濾、排序、分頁或限制結果集中的屬性集。

6.1. 過濾

我們可以通過使用 cayenneExp 參數來基於屬性值過濾結果。正如其名稱所示,這遵循 Cayenne 表達式 的格式。

讓我們發送一個只返回名稱為“IT”的部門的請求:

curl -i -X GET http://localhost:8080/linkrest/department?cayenneExp=name='IT'

6.2. 排序

要對一組結果進行排序,需要添加的參數包括 sortdir。其中,前者指定排序的屬性,後者指定排序方向。

以下是按部門名稱對所有部門進行排序的結果:

curl -i -X GET "http://localhost:8080/linkrest/department?sort=name&dir=ASC"

6.3. 分頁

該庫通過添加 startlimit 參數來支持分頁:

curl -i -X GET "http://localhost:8080/linkrest/department?start=0&limit=2

6.4. 選擇屬性

使用 includeexclude 參數,我們可以控制結果中返回的屬性或關係。

例如,讓我們發送一個僅顯示部門名稱的請求:

curl -i -X GET "http://localhost:8080/linkrest/department?include=name

為了顯示部門中的員工姓名及其姓名,僅使用姓名,我們可以使用 include 屬性兩次:

curl -i -X GET "http://localhost:8080/linkrest/department?include=name&include=employees.name

7. 結論

在本文中,我們展示瞭如何通過使用 LinkRest 框架,快速地通過 REST 端點暴露數據模型。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.