$ 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
-
cd into
{project_id}/initial
-
跳到 存取 Neo4j 的權限。
當您完成時,您可以根據 {project_id}/complete
中的程式碼檢查您的結果。
啟動 Neo4j 伺服器
在您可以建置此應用程式之前,您需要設定 Neo4j 伺服器。
Neo4j 有一個您可以免費安裝的開放原始碼伺服器。
在安裝了 Homebrew 的 Mac 上,您可以在終端機視窗中輸入以下內容
安裝 Neo4j 後,您可以執行以下命令以預設設定啟動它
$ neo4j start
您應該會看到類似以下的訊息
Starting Neo4j. Started neo4j (pid 96416). By default, it is available at https://127.0.0.1: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
和 neo4j
。但是,它要求變更新帳戶密碼。若要執行此操作,請執行以下命令
$ curl -v -u neo4j:neo4j POST localhost:7474/user/neo4j/password -H "Content-type:application/json" -d "{\"password\":\"secret\"}"
這會將密碼從 neo4j
變更為 secret
(在生產環境中絕對不能這樣做!) 完成後,您應該可以執行本指南了。
從 Spring Initializr 開始
您可以使用這個 預先初始化的專案,然後按一下 [Generate] 下載 ZIP 檔案。此專案已設定為符合本教學課程中的範例。
若要手動初始化專案
-
瀏覽至 https://start.spring.io。此服務會提取應用程式所需的所有相依性,並為您完成大部分設定。
-
選擇 Gradle 或 Maven 以及您想要使用的語言。本指南假設您選擇 Java。
-
按一下 [Dependencies] 並選取 [Rest Repositories] 和 [Spring Data Neo4j]。
-
按一下 [Generate]。
-
下載產生的 ZIP 檔案,該檔案是使用您的選擇設定的 Web 應用程式的封存檔。
如果您的 IDE 具有 Spring Initializr 整合,您可以從 IDE 完成此流程。 |
您也可以從 Github 分支專案,並在您的 IDE 或其他編輯器中開啟它。 |
存取 Neo4j 的權限
Neo4j Community Edition 需要憑證才能存取。您可以透過在 src/main/resources/application.properties
中設定屬性來設定憑證,如下所示
spring.neo4j.uri=bolt://127.0.0.1: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://127.0.0.1:8080
{
"_links" : {
"people" : {
"href" : "https://127.0.0.1:8080/people{?page,size,sort}",
"templated" : true
}
}
}
在這裡,您可以初步了解此伺服器提供的內容。有一個 people
連結位於 https://127.0.0.1:8080/people。它具有一些選項,例如 ?page
、?size
和 ?sort
。
Spring Data REST 使用 HAL 格式 進行 JSON 輸出。它很靈活,並提供了一種方便的方式來提供與所服務資料相鄰的連結。 |
$ curl https://127.0.0.1:8080/people
{
"_links" : {
"self" : {
"href" : "https://127.0.0.1:8080/people{?page,size,sort}",
"templated" : true
},
"search" : {
"href" : "https://127.0.0.1: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://127.0.0.1:8080/people
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Location: https://127.0.0.1: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://127.0.0.1:8080/people
{
"_links" : {
"self" : {
"href" : "https://127.0.0.1:8080/people{?page,size,sort}",
"templated" : true
},
"search" : {
"href" : "https://127.0.0.1:8080/people/search"
}
},
"_embedded" : {
"people" : [ {
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "https://127.0.0.1:8080/people/0"
}
}
} ]
},
"page" : {
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
}
}
people
物件包含包含佛羅多的清單。請注意它如何包含 self
連結。Spring Data REST 也使用 Evo Inflector 程式庫來將群組的實體名稱複數化。
您可以執行以下命令 (及其輸出) 直接查詢個別記錄
$ curl https://127.0.0.1:8080/people/0
{
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "https://127.0.0.1:8080/people/0"
}
}
}
這可能看起來純粹是基於 Web 的,但實際上,後端有一個內嵌的 Neo4j 圖形資料庫。在生產環境中,您可能會連線到獨立的 Neo4j 伺服器。 |
在本指南中,只有一個網域物件。對於更複雜的系統,網域物件彼此相關,Spring Data REST 會呈現其他連結,以協助瀏覽到連線的記錄。
您可以執行以下命令 (及其輸出) 找到所有自訂查詢
$ curl https://127.0.0.1:8080/people/search
{
"_links" : {
"findByLastName" : {
"href" : "https://127.0.0.1:8080/people/search/findByLastName{?name}",
"templated" : true
}
}
}
您可以看到查詢的 URL,包括 HTTP 查詢參數:name
。請注意,這與介面中內嵌的 @Param("name")
註解相符。
若要使用 findByLastName
查詢,請執行以下命令 (及其輸出)
$ curl https://127.0.0.1:8080/people/search/findByLastName?name=Baggins
{
"_embedded" : {
"people" : [ {
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "https://127.0.0.1:8080/people/0"
},
"person" : {
"href" : "https://127.0.0.1:8080/people/0"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "https://127.0.0.1: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://127.0.0.1:8080/people/0
$ curl https://127.0.0.1:8080/people/0
{
"firstName" : "Bilbo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "https://127.0.0.1:8080/people/0"
}
}
}
以下範例 (及其輸出) 顯示 PATCH
呼叫
$ curl -X PATCH -H "Content-Type:application/json" -d '{ "firstName": "Bilbo Jr." }' https://127.0.0.1:8080/people/0
$ curl https://127.0.0.1:8080/people/0
{
"firstName" : "Bilbo Jr.",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "https://127.0.0.1:8080/people/0"
}
}
}
PUT 會取代整個記錄。未提供的欄位會取代為 null 。PATCH 可用於更新項目的子集。 |
您也可以刪除記錄,如下列範例 (及其輸出) 所示
$ curl -X DELETE https://127.0.0.1:8080/people/0
$ curl https://127.0.0.1:8080/people
{
"_links" : {
"self" : {
"href" : "https://127.0.0.1:8080/people{?page,size,sort}",
"templated" : true
},
"search" : {
"href" : "https://127.0.0.1:8080/people/search"
}
},
"page" : {
"size" : 20,
"totalElements" : 0,
"totalPages" : 0,
"number" : 0
}
}
這種超媒體驅動介面的一個方便之處在於,您可以使用 curl (或您喜歡的任何 REST 用戶端) 探索所有 RESTful 端點。您無需與您的客戶交換正式合約或介面文件。
摘要
恭喜!您剛剛開發了一個具有 基於超媒體 的 RESTful 前端和基於 Neo4j 的後端的應用程式。