$ brew install neo4j
使用 REST 訪問 Neo4j 資料
本指南將引導您完成建立一個應用程式的過程,該應用程式透過基於超媒體的 RESTful 前端訪問基於圖的資料。
您將構建什麼
您將構建一個 Spring 應用程式,它允許您使用 Spring Data REST 建立和檢索儲存在 Neo4j NoSQL 資料庫中的 Person 物件。Spring Data REST 結合了 Spring HATEOAS 和 Spring Data Neo4j 的功能,並自動將它們組合在一起。
| Spring Data REST 還支援 Spring Data JPA、Spring Data Gemfire 和 Spring Data MongoDB 作為後端資料儲存,但本指南只涉及 Neo4j。 |
你需要什麼
-
大約 15 分鐘
-
一個喜歡的文字編輯器或 IDE
-
Java 17 或更高版本
-
您還可以將程式碼直接匯入到您的 IDE 中
如何完成本指南
與大多數 Spring 入門指南一樣,您可以從頭開始並完成每個步驟,也可以跳過您已熟悉的基本設定步驟。無論哪種方式,您最終都會得到可工作的程式碼。
要從頭開始,請轉到[從頭開始]。
要跳過基礎知識,請執行以下操作
-
下載並解壓本指南的源儲存庫,或者使用 Git 克隆它:
git clone https://github.com/spring-guides/{project_id}.git -
進入
{project_id}/initial
完成後,您可以將結果與 {project_id}/complete 中的程式碼進行比較。
搭建 Neo4j 伺服器
在構建此應用程式之前,您需要設定一個 Neo4j 伺服器。
Neo4j 有一個開源伺服器,您可以免費安裝。
在安裝了 Homebrew 的 Mac 上,您可以在終端視窗中鍵入以下內容
安裝 Neo4j 後,您可以透過執行以下命令以其預設設定啟動它
$ neo4j start
您應該會看到類似以下訊息
Starting Neo4j. Started neo4j (pid 96416). By default, it is available at https://:7474/ There may be a short delay until the server is ready. See /usr/local/Cellar/neo4j/3.0.6/libexec/logs/neo4j.log for current status.
預設情況下,Neo4j 的使用者名稱和密碼均為 neo4j。但是,它要求更改新賬戶密碼。為此,請執行以下命令
$ curl -v -u neo4j:neo4j POST localhost:7474/user/neo4j/password -H "Content-type:application/json" -d "{\"password\":\"secret\"}"
這將密碼從 neo4j 更改為 secret(在生產環境中不要這樣做!)。完成後,您應該已準備好執行本指南。
從 Spring Initializr 開始
您可以使用此預初始化專案,然後單擊“生成”下載 ZIP 檔案。此專案已配置為符合本教程中的示例。
手動初始化專案
-
導航到 https://start.spring.io。此服務會為您拉取應用程式所需的所有依賴項,併為您完成大部分設定。
-
選擇 Gradle 或 Maven 以及您想要使用的語言。本指南假設您選擇了 Java。
-
點選 Dependencies 並選擇 Rest Repositories 和 Spring Data Neo4j。
-
單擊生成。
-
下載生成的 ZIP 檔案,這是一個已根據您的選擇配置好的 Web 應用程式存檔。
| 如果您的 IDE 集成了 Spring Initializr,您可以從 IDE 中完成此過程。 |
| 您還可以從 Github fork 該專案並在您的 IDE 或其他編輯器中開啟它。 |
訪問 Neo4j 的許可權
Neo4j 社群版需要憑據才能訪問。您可以透過在 src/main/resources/application.properties 中設定屬性來配置憑據,如下所示
spring.neo4j.uri=bolt://:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=secret
這包括您之前設定的預設使用者名稱(neo4j)和新設定的密碼(secret)。
| 請勿將實際憑據儲存在您的原始碼倉庫中。相反,請使用Spring Boot 的屬性覆蓋在執行時配置它們。 |
建立領域物件
您需要建立一個新的領域物件來表示一個人,如下面的示例(在 src/main/java/com/example/accessingneo4jdatarest/Person.java 中)所示
package com.example.accessingneo4jdatarest;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
@Node
public class Person {
@Id @GeneratedValue private Long 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/accessingneo4jdatarest/PersonRepository.java 中)所示
package com.example.accessingneo4jdatarest;
import java.util.List;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long>, CrudRepository<Person, Long> {
List<Person> findByLastName(@Param("name") String name);
}
此儲存庫是一個介面,允許您執行涉及 Person 物件的各種操作。它透過擴充套件 Spring Data Commons 中定義的 PagingAndSortingRepositry 介面來獲取這些操作。
在執行時,Spring Data REST 自動建立此介面的實現。然後它使用 @RepositoryRestResource 註解指示 Spring MVC 在 /people 建立 RESTful 端點。
匯出儲存庫不需要 @RepositoryRestResource。它僅用於更改匯出詳細資訊,例如使用 /people 而不是預設值 /persons。 |
這裡您還定義了一個自定義查詢,用於根據 lastName 值檢索 Person 物件的列表。您可以在本指南後面看到如何呼叫它。
查詢應用程式類
當您使用 Spring Initializr 建立專案時,它會建立一個應用程式類。您可以在 src/main/java/com/example/accessingneo4jdatarest/Application.java 中找到它。請注意,Spring Initializr 會連線(並正確更改大小寫)包名並將其新增到 Application 以建立應用程式類名。在這種情況下,我們得到 AccessingNeo4jDataRestApplication,如下面的列表所示
package com.example.accessingneo4jdatarest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@EnableNeo4jRepositories
@SpringBootApplication
public class AccessingNeo4jDataRestApplication {
public static void main(String[] args) {
SpringApplication.run(AccessingNeo4jDataRestApplication.class, args);
}
}
對於本示例,您無需對這個應用程式類進行任何更改
@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,您不必處理任何管道或基礎設施的配置。
@EnableNeo4jRepositories 註解啟用 Spring Data Neo4j。Spring Data Neo4j 建立 PersonRepository 的具體實現,並配置它使用 Cypher 查詢語言與嵌入式 Neo4j 資料庫通訊。
構建可執行 JAR
您可以使用 Gradle 或 Maven 從命令列執行應用程式。您還可以構建一個包含所有必要依賴項、類和資源並執行的單個可執行 JAR 檔案。構建可執行 JAR 使在整個開發生命週期中,跨不同環境等,輕鬆交付、版本化和部署服務作為應用程式。
如果您使用 Gradle,您可以透過使用 ./gradlew bootRun 執行應用程式。或者,您可以透過使用 ./gradlew build 構建 JAR 檔案,然後按如下方式執行 JAR 檔案
如果您使用 Maven,您可以透過使用 ./mvnw spring-boot:run 執行應用程式。或者,您可以使用 ./mvnw clean package 構建 JAR 檔案,然後按如下方式執行 JAR 檔案
| 這裡描述的步驟建立了一個可執行的 JAR。您還可以構建一個經典的 WAR 檔案。 |
日誌輸出已顯示。服務應在幾秒鐘內啟動並執行。
測試應用程式
現在應用程式已執行,您可以對其進行測試。您可以使用任何您喜歡的 REST 客戶端。以下示例使用名為 curl 的 *nix 工具。
首先,您想檢視頂層服務。以下示例(帶輸出)展示瞭如何操作
$ curl https://:8080
{
"_links" : {
"people" : {
"href" : "https://:8080/people{?page,size,sort}",
"templated" : true
}
}
}
這裡您第一次瞭解了這個伺服器可以提供什麼。在 https://:8080/people 有一個 people 連結。它有一些選項,例如 ?page、?size 和 ?sort。
| Spring Data REST 使用 HAL 格式進行 JSON 輸出。它靈活方便,提供了一種在所服務資料旁邊提供連結的方法。 |
$ 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 了!為此,請執行以下命令(顯示其輸出)
$ 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/0
Content-Length: 0
Date: Wed, 26 Feb 2014 20:26:55 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(…) 和 setReturnBodyOnCreate(…)),您可以使用它們來配置框架,使其在建立資源後立即返回資源的表示。 |
由此,您可以透過執行以下命令(顯示其輸出)查詢所有人員
$ curl https://:8080/people
{
"_links" : {
"self" : {
"href" : "https://:8080/people{?page,size,sort}",
"templated" : true
},
"search" : {
"href" : "https://:8080/people/search"
}
},
"_embedded" : {
"people" : [ {
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "https://:8080/people/0"
}
}
} ]
},
"page" : {
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
}
}
people 物件包含一個帶有 Frodo 的列表。注意它如何包含一個 self 連結。Spring Data REST 還使用 Evo Inflector 庫將實體名稱複數化以進行分組。
您可以透過執行以下命令(顯示其輸出)直接查詢單個記錄
$ curl https://:8080/people/0
{
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "https://:8080/people/0"
}
}
}
| 這可能看起來純粹基於網路,但幕後有一個嵌入式的 Neo4j 圖資料庫。在生產環境中,您可能會連線到獨立的 Neo4j 伺服器。 |
在本指南中,只有一個領域物件。在一個更復雜的系統中,如果領域物件之間存在關聯,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" : {
"people" : [ {
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "https://:8080/people/0"
},
"person" : {
"href" : "https://:8080/people/0"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "https://:8080/people/search/findByLastName?name=Baggins"
}
}
}
由於您在程式碼中將其定義為返回 List<Person>,因此它會返回所有結果。如果您將其定義為僅返回 Person,它將選擇一個 Person 物件返回。由於這可能是不可預測的,因此對於可以返回多個條目的查詢,您可能不希望這樣做。
您還可以發出 PUT、PATCH 和 DELETE REST 呼叫,以替換、更新或刪除現有記錄。以下示例(顯示其輸出)展示了一個 PUT 呼叫
$ curl -X PUT -H "Content-Type:application/json" -d '{ "firstName": "Bilbo", "lastName": "Baggins" }' https://:8080/people/0
$ curl https://:8080/people/0
{
"firstName" : "Bilbo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "https://:8080/people/0"
}
}
}
以下示例(顯示其輸出)展示了一個 PATCH 呼叫
$ curl -X PATCH -H "Content-Type:application/json" -d '{ "firstName": "Bilbo Jr." }' https://:8080/people/0
$ curl https://:8080/people/0
{
"firstName" : "Bilbo Jr.",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "https://:8080/people/0"
}
}
}
PUT 替換整個記錄。未提供的欄位將替換為 null。PATCH 可用於更新專案子集。 |
您還可以刪除記錄,如下面的示例(顯示其輸出)所示
$ curl -X DELETE https://:8080/people/0
$ 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 端點。您無需與客戶交換正式的合同或介面文件。
總結
恭喜!您剛剛開發了一個具有基於超媒體的 RESTful 前端和基於 Neo4j 的後端的應用程式。