使用 REST 訪問 MongoDB 資料

本指南將引導您完成建立應用程式的過程,該應用程式透過一個基於超媒體的 RESTful 前端訪問基於文件的資料。

您將構建什麼

您將構建一個 Spring 應用程式,該程式允許您使用 Spring Data REST 建立和檢索儲存在 MongoDB NoSQL 資料庫中的 Person 物件。Spring Data REST 融合了 Spring HATEOASSpring Data MongoDB 的特性,並自動將它們結合在一起。

Spring Data REST 也支援 Spring Data JPASpring Data GemfireSpring Data Neo4j 作為後端資料儲存,但這些不是本指南的一部分。

所需條件

如何完成本指南

與大多數 Spring 入門指南 類似,您可以從頭開始完成每個步驟,也可以跳過您已經熟悉的基本設定步驟。無論哪種方式,您最終都會獲得可執行的程式碼。

從頭開始,請轉到使用 Spring Initializr 入門

跳過基礎部分,請執行以下操作

完成後,您可以將您的結果與 gs-accessing-mongodb-data-rest/complete 中的程式碼進行對照檢查。

使用 Spring Initializr 入門

您可以使用這個預配置的專案,然後點選 Generate 下載 ZIP 檔案。這個專案已配置好,適用於本教程中的示例。

手動初始化專案

  1. 導航到 https://start.spring.io。該服務會為您拉取應用程式所需的所有依賴項,並完成大部分設定工作。

  2. 選擇 Gradle 或 Maven 以及您想要使用的語言。本指南假定您選擇了 Java。

  3. 點選 Dependencies 並選擇 Rest RepositoriesSpring Data MongoDB

  4. 點選 Generate

  5. 下載生成的 ZIP 檔案,這是一個根據您的選擇配置好的 Web 應用程式存檔。

如果您的 IDE 集成了 Spring Initializr,您可以直接從 IDE 完成此過程。
您也可以從 Github Fork 專案,並在您的 IDE 或其他編輯器中開啟它。

安裝並啟動 MongoDB

要使本指南起作用,您必須搭建一個本地 MongoDB 伺服器。

在安裝了 Homebrew 的 Mac OS X 機器上,執行以下命令

brew install mongodb

您可以在 https://docs.mongodb.org/manual/installation/ 找到更多安裝選項。

安裝 MongoDB 後,您需要啟動 mongo 守護程式。在 Mac 上,您可以使用以下命令

$ mongod
all output going to: /usr/local/var/log/mongodb/mongo.log

您可以透過執行 mongo 命令從另一個終端視窗啟動 MongoDB 客戶端。

建立領域物件

建立一個新的領域物件來表示一個人,如以下示例(在 src/main/java/com/example/accessingmongodbdatarest/Person.java 中)所示

package com.example.accessingmongodbdatarest;

import org.springframework.data.annotation.Id;

public class Person {

  @Id private String id;

  private String firstName;
  private String lastName;

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
}

Person 物件具有名字和姓氏。(還有一個 ID 物件,它被配置為自動生成,因此無需處理。)

建立 Person 倉庫

接下來,您需要建立一個簡單的倉庫,如以下清單(在 src/main/java/com/example/accessingmongodbdatarest/PersonRepository.java 中)所示

package com.example.accessingmongodbdatarest;

import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository extends MongoRepository<Person, String> {

  List<Person> findByLastName(@Param("name") String name);

}

這個倉庫是一個介面,允許您執行涉及 Person 物件的各種操作。它透過繼承 MongoRepository 獲取這些操作,而 MongoRepository 又擴充套件了在 Spring Data Commons 中定義的 PagingAndSortingRepository 介面。

在執行時,Spring Data REST 會自動建立此介面的實現。然後它使用 @RepositoryRestResource 註解來指示 Spring MVC 在 /people 建立 RESTful 端點。

倉庫的匯出不是必需使用 @RepositoryRestResource 的。它僅用於更改匯出細節,例如使用 /people 而不是預設值 /persons

在這裡,您還定義了一個自定義查詢,用於根據 lastName 值檢索 Person 物件列表。您可以在本指南的後續部分看到如何呼叫它。

預設情況下,Spring Boot 會嘗試連線到本地託管的 MongoDB 例項。閱讀參考文件,瞭解如何將您的應用程式指向託管在其他位置的 MongoDB 例項。

@SpringBootApplication 是一個便捷註解,它包含了以下所有註解

  • @Configuration:將類標記為應用程式上下文的 bean 定義源。

  • @EnableAutoConfiguration:告訴 Spring Boot 根據類路徑設定、其他 bean 和各種屬性設定開始新增 bean。例如,如果類路徑上有 spring-webmvc,此註解會將應用程式標記為 Web 應用程式並激活關鍵行為,例如設定 DispatcherServlet

  • @ComponentScan:告訴 Spring 在 com/example 包中查詢其他元件、配置和服務,使其能夠找到控制器。

main() 方法使用 Spring Boot 的 SpringApplication.run() 方法啟動應用程式。您注意到沒有一行 XML 程式碼嗎?也沒有 web.xml 檔案。這個 Web 應用程式是 100% 純 Java 的,您無需處理任何底層或基礎設施的配置。

構建可執行 JAR

您可以使用 Gradle 或 Maven 從命令列執行應用程式。您還可以構建一個包含所有必需依賴項、類和資源的單一可執行 JAR 檔案並執行它。構建可執行 JAR 檔案使得在整個開發生命週期中、跨不同環境以及其他情況下,輕鬆交付、版本化和部署該服務作為應用程式成為可能。

如果您使用 Gradle,可以透過執行 ./gradlew bootRun 來執行應用程式。或者,您可以使用 ./gradlew build 構建 JAR 檔案,然後按如下方式執行 JAR 檔案

java -jar build/libs/gs-accessing-mongodb-data-rest-0.1.0.jar

如果您使用 Maven,可以透過執行 ./mvnw spring-boot:run 來執行應用程式。或者,您可以使用 ./mvnw clean package 構建 JAR 檔案,然後按如下方式執行 JAR 檔案

java -jar target/gs-accessing-mongodb-data-rest-0.1.0.jar
這裡描述的步驟將建立一個可執行的 JAR 檔案。您還可以構建一個經典的 WAR 檔案

將顯示日誌輸出。該服務應在幾秒鐘內啟動並執行。

測試應用程式

應用程式現在正在執行,您可以測試它。您可以使用任何您想要的 REST 客戶端。以下示例使用 *nix 工具 curl

首先,您需要檢視頂層服務,如以下示例所示

$ curl https://:8080
{
  "_links" : {
    "people" : {
      "href" : "https://:8080/people{?page,size,sort}",
      "templated" : true
    }
  }
}

前面的示例首次展示了該伺服器提供的功能。在 https://:8080/people 有一個 people 連結。它有一些選項,例如 ?page?size?sort

Spring Data REST 對 JSON 輸出使用 HAL 格式。它非常靈活,提供了一種方便的方式來提供與提供的資料相鄰的連結。

使用 people 連結時,您會看到資料庫中的 Person 記錄(目前沒有)

$ curl https://:8080/people
{
  "_links" : {
    "self" : {
      "href" : "https://:8080/people{?page,size,sort}",
      "templated" : true
    },
    "search" : {
      "href" : "https://:8080/people/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 0,
    "totalPages" : 0,
    "number" : 0
  }
}

目前沒有元素,因此也沒有頁面。是時候建立一個新的 Person 了!

如果您多次執行本指南,可能會有殘留資料。如果您需要重新開始,請查閱 MongoDB shell 快速參考 以獲取查詢和刪除資料庫的命令。

以下命令建立一個名為“Frodo Baggins”的人

$ curl -i -X POST -H "Content-Type:application/json" -d "{  \"firstName\" : \"Frodo\",  \"lastName\" : \"Baggins\" }" https://:8080/people
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Location: https://:8080/people/53149b8e3004990b1af9f229
Content-Length: 0
Date: Mon, 03 Mar 2014 15:08:46 GMT
  • -i:確保您能看到響應訊息,包括頭部資訊。將顯示新建立的 Person 的 URI。

  • -X POST:表示這是一個用於建立新條目的 POST 請求。

  • -H "Content-Type:application/json":設定內容型別,以便應用程式知道請求體包含 JSON 物件。

  • -d '{ "firstName" : "Frodo", "lastName" : "Baggins" }':這是傳送的資料。

請注意,前面的 POST 操作包含一個 Location 頭部。這包含新建立資源的 URI。Spring Data REST 還有兩個方法(RepositoryRestConfiguration.setReturnBodyOnCreate(…)setReturnBodyOnUpdate(…)),您可以使用它們來配置框架,以便立即返回剛剛建立/更新的資源的表示。

透過這個,您可以查詢所有的人,如以下示例所示

$ curl https://:8080/people
{
  "_links" : {
    "self" : {
      "href" : "https://:8080/people{?page,size,sort}",
      "templated" : true
    },
    "search" : {
      "href" : "https://:8080/people/search"
    }
  },
  "_embedded" : {
    "persons" : [ {
      "firstName" : "Frodo",
      "lastName" : "Baggins",
      "_links" : {
        "self" : {
          "href" : "https://:8080/people/53149b8e3004990b1af9f229"
        }
      }
    } ]
  },
  "page" : {
    "size" : 20,
    "totalElements" : 1,
    "totalPages" : 1,
    "number" : 0
  }
}

persons 物件包含一個包含 Frodo 的列表。注意它如何包含一個 self 連結。Spring Data REST 還使用 Evo Inflector 來對分組的實體名稱進行復數化。

您可以直接查詢單個記錄,如以下示例所示

$ curl https://:8080/people/53149b8e3004990b1af9f229
{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "https://:8080/people/53149b8e3004990b1af9f229"
    }
  }
}
這看起來可能純粹是基於 Web 的,但其背後,它正在與您啟動的 MongoDB 資料庫進行通訊。

在本指南中,只有一個領域物件。在更復雜的系統中,如果領域物件相互關聯,Spring Data REST 會呈現額外的連結以幫助導航到相關記錄。

查詢所有自定義查詢,如以下示例所示

$ curl https://:8080/people/search
{
  "_links" : {
    "findByLastName" : {
      "href" : "https://:8080/people/search/findByLastName{?name}",
      "templated" : true
    }
  }
}

您可以看到查詢的 URL,包括 HTTP 查詢引數 name。這與嵌入在介面中的 @Param("name") 註解相匹配。

要使用 findByLastName 查詢,執行以下命令

$ curl https://:8080/people/search/findByLastName?name=Baggins
{
  "_embedded" : {
    "persons" : [ {
      "firstName" : "Frodo",
      "lastName" : "Baggins",
      "_links" : {
        "self" : {
          "href" : "https://:8080/people/53149b8e3004990b1af9f229"
        }
      }
    } ]
  }
}

因為您在程式碼中將其定義為返回 List<Person>,所以它返回所有結果。如果您將其定義為僅返回 Person,它會從中選擇一個 Person 物件返回。由於這可能不可預測,對於可以返回多個條目的查詢,您可能不希望這樣做。

您還可以發出 PUTPATCHDELETE REST 呼叫,分別用於替換、更新或刪除現有記錄。以下示例使用一個 PUT 呼叫

$ curl -X PUT -H "Content-Type:application/json" -d "{ \"firstName\": \"Bilbo\", \"lastName\": \"Baggins\" }" https://:8080/people/53149b8e3004990b1af9f229
$ curl https://:8080/people/53149b8e3004990b1af9f229
{
  "firstName" : "Bilbo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "https://:8080/people/53149b8e3004990b1af9f229"
    }
  }
}

以下示例使用一個 PATCH 呼叫

$ curl -X PATCH -H "Content-Type:application/json" -d "{ \"firstName\": \"Bilbo Jr.\" }" https://:8080/people/53149b8e3004990b1af9f229
$ curl https://:8080/people/53149b8e3004990b1af9f229
{
  "firstName" : "Bilbo Jr.",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "https://:8080/people/53149b8e3004990b1af9f229"
    }
  }
}
PUT 替換整個記錄。未提供的欄位將被替換為 null。您可以使用 PATCH 更新專案子集。

您還可以刪除記錄,如以下示例所示

$ curl -X DELETE https://:8080/people/53149b8e3004990b1af9f229
$ curl https://:8080/people
{
  "_links" : {
    "self" : {
      "href" : "https://:8080/people{?page,size,sort}",
      "templated" : true
    },
    "search" : {
      "href" : "https://:8080/people/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 0,
    "totalPages" : 0,
    "number" : 0
  }
}

這種超媒體驅動的介面的一個便捷之處在於,您可以使用 curl(或任何您喜歡的 REST 客戶端)發現所有 RESTful 端點。無需與您的客戶交換正式的契約或介面文件。

總結

恭喜您!您剛剛開發了一個具有基於超媒體的 REST 前端和基於 MongoDB 後端的應用程式。

獲取程式碼