使用 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 開始

您可以使用此預初始化專案,然後單擊“生成”下載 ZIP 檔案。此專案已配置為符合本教程中的示例。

手動初始化專案

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

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

  3. 單擊依賴項並選擇Rest RepositoriesSpring Data MongoDB

  4. 單擊生成

  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
    }
  }
}

前面的示例初步展示了此伺服器提供的功能。有一個 people 連結位於 https://:8080/people。它有一些選項,例如 ?page?size?sort

Spring Data REST 使用 HAL 格式進行 JSON 輸出。它靈活方便,提供了一種在所服務資料旁邊提供連結的方法。

當您使用 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"
    }
  }
}
這可能看起來純粹是基於網路的,但實際上,它正在與您啟動的 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 的後端的應用程式。

獲取程式碼