このガイドでは、ハイパーメディアベースREST フルフロントエンド (英語) を介して Pivotal GemFire データにアクセスするアプリケーションを作成するプロセスを順を追って説明します。

構築する

Spring Data REST を使用して、Pivotal GemFire インメモリデータグリッドに保存されている Person オブジェクトを作成および取得できる Spring Web アプリケーションを構築します。Spring Data REST は、Spring HATEOAS および Spring Data for Pivotal GemFire の機能を使用して、自動的に結合します。

Spring Data REST は、バックエンドデータストアとして Spring Data JPASpring Data MongoDB および Spring Data Neo4j もサポートしていますが、これらはこのガイドの一部ではありません。
Pivotal GemFire の概念のより一般的な知識および Pivotal GemFire のデータへのアクセスについては、ガイド Pivotal GemFire を使用したデータへのアクセスを参照してください。

必要なもの

このガイドを完了する方法

ほとんどの Spring 入門ガイドと同様に、最初から始めて各ステップを完了するか、すでに慣れている場合は基本的なセットアップステップをバイパスできます。いずれにしても、最終的に動作するコードになります。

最初から始めるには、Gradle でビルドするに進みます。

基本スキップするには、次の手順を実行します。

完了したときは、gs-accessing-gemfire-data-rest/complete のコードに対して結果を確認できます。

Gradle でビルドする

Gradle でビルドする

最初に、基本的なビルドスクリプトを設定します。Spring を使用してアプリをビルドする場合、好きなビルドシステムを使用できますが、Gradle (英語) および Maven (英語) を操作するために必要なコードはここに含まれています。どちらにも詳しくない場合は、Gradle で Java プロジェクトの構築または Maven で Java プロジェクトの構築を参照してください。

ディレクトリ構造を作成する

選択したプロジェクトディレクトリで、次のサブディレクトリ構造を作成します。たとえば、*nix システム上の mkdir -p src/main/java/hello の場合:

 └──  src
     └──  main
         └──  java
             └──  hello

Gradle ビルドファイルを作成する

build.gradle

buildscript {
    repositories {
        mavenCentral()
        maven { url "https://repo.spring.io/libs-release" }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.2.1.RELEASE")
    }
}

plugins {
    id "io.spring.dependency-management" version "1.0.5.RELEASE"
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

sourceCompatibility = 1.8
targetCompatibility = 1.8

bootJar {
    baseName = 'gs-accessing-gemfire-data-rest'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
    maven { url "https://repo.spring.io/libs-release" }
}

dependencies {

    compile("org.springframework.boot:spring-boot-starter-data-rest") {
        exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
    }
    compile("org.springframework.data:spring-data-gemfire")
    compile("org.projectlombok:lombok")

    runtime("org.springframework.shell:spring-shell:1.2.0.RELEASE")

    testCompile("org.springframework.boot:spring-boot-starter-test") {
        exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
    }
}

Spring Boot gradle プラグインは多くの便利な機能を提供します。

  • クラスパス上のすべての jar を収集し、単一の実行可能な「ü ber-jar」を構築します。これにより、サービスの実行とトランスポートがより便利になります。

  • public static void main() メソッドを検索して、実行可能なクラスとしてフラグを立てます。

  • Spring Boot の依存関係 (GitHub) と一致するようにバージョン番号を設定する組み込みの依存関係リゾルバーを提供します。任意のバージョンをオーバーライドできますが、デフォルトでブートの選択されたバージョンのセットになります。

Maven でビルドする

Maven でビルドする

最初に、基本的なビルドスクリプトを設定します。Spring を使用してアプリをビルドする場合、好きなビルドシステムを使用できますが、Maven (英語) で作業するために必要なコードはここに含まれています。Maven に詳しくない場合は、Maven で Java プロジェクトの構築を参照してください。

ディレクトリ構造を作成する

選択したプロジェクトディレクトリで、次のサブディレクトリ構造を作成します。たとえば、*nix システム上の mkdir -p src/main/java/hello の場合:

 └──  src
     └──  main
         └──  java
             └──  hello

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>

    <groupId>org.springframework</groupId>
    <artifactId>gs-accessing-gemfire-data-rest</artifactId>
    <version>0.1.0</version>

    <properties>
        <spring-shell.version>1.2.0.RELEASE</spring-shell.version>
    </properties>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-gemfire</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.shell</groupId>
            <artifactId>spring-shell</artifactId>
            <version>${spring-shell.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Spring Boot Maven プラグインは多くの便利な機能を提供します。

  • クラスパス上のすべての jar を収集し、単一の実行可能な「ü ber-jar」を構築します。これにより、サービスの実行とトランスポートがより便利になります。

  • public static void main() メソッドを検索して、実行可能なクラスとしてフラグを立てます。

  • Spring Boot の依存関係 (GitHub) と一致するようにバージョン番号を設定する組み込みの依存関係リゾルバーを提供します。任意のバージョンをオーバーライドできますが、デフォルトでブートの選択されたバージョンのセットになります。

IDE でビルドする

IDE でビルドする

ドメインオブジェクトを作成する

新しいドメインオブジェクトを作成して、人物を紹介します。

src/main/java/hello/Person.java

package hello;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.gemfire.mapping.annotation.Region;

import lombok.Data;

@Data
@Region("People")
public class Person {

  private static AtomicLong COUNTER = new AtomicLong(0L);

  @Id
  private Long id;

  private String firstName;
  private String lastName;

  @PersistenceConstructor
  public Person() {
    this.id = COUNTER.incrementAndGet();
  }
}

Person には姓と名があります。Pivotal GemFire ドメインオブジェクトには ID が必要であるため、Person オブジェクトの作成ごとに AtomicLong を使用して増分します。

個人リポジトリを作成する

次に、Pivotal GemFire に保存されている Person オブジェクトを永続化 / アクセスするための簡単なリポジトリを作成する必要があります。

src/main/java/hello/PersonRepository.java

package hello;

import java.util.List;

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 CrudRepository<Person, Long> {

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

}

このリポジトリはインターフェースであり、Person オブジェクトに関連するさまざまなデータアクセス操作(基本的な CRUD や単純なクエリなど)を実行できます。CrudRepository を継承することにより、これらの操作を取得します。

実行時に、Pivotal GemFire の Spring Data は、このインターフェースの実装を自動的に作成します。次に、Spring Data REST は @RepositoryRestResource (英語) アノテーションを使用して Spring MVC に /people で REST-ful エンドポイントを作成するよう指示します。

@RepositoryRestResource は、リポジトリのエクスポートには必要ありません。/persons のデフォルト値の代わりに /people を使用するなど、エクスポートの詳細を変更するためにのみ使用されます。

ここでは、lastName に基づいて Person オブジェクトのリストを取得するカスタムクエリも定義しました。このガイドのさらに下で呼び出す方法がわかります。

アプリケーションを実行可能にする

このサービスをデプロイの従来の WAR (英語) ファイルとして外部アプリケーションサーバーにパッケージ化することは可能ですが、以下に示すより単純なアプローチでは、スタンドアロンアプリケーションが作成されます。古き良き Java main() メソッドによって駆動される単一の実行可能な JAR ファイルにすべてをパッケージ化します。その過程で、外部のサーブレットコンテナーにデプロイする代わりに、Tomcat (英語) サーブレットコンテナーを HTTP ランタイムとして埋め込むための Spring のサポートを使用します。

src/main/java/hello/Application.java

package hello;

import org.apache.geode.cache.client.ClientRegionShortcut;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;

@SpringBootApplication
@ClientCacheApplication(name = "AccessingGemFireDataRestApplication", logLevel = "error")
@EnableEntityDefinedRegions(basePackageClasses = Person.class,
  clientRegionShortcut = ClientRegionShortcut.LOCAL)
@EnableGemfireRepositories
@SuppressWarnings("unused")
public class Application {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

@SpringBootApplication は、次のすべてを追加する便利なアノテーションです。

  • @Configuration: アプリケーションコンテキストの Bean 定義のソースとしてクラスにタグを付けます。

  • @EnableAutoConfiguration: クラスパス設定、他の Bean、およびさまざまなプロパティ設定に基づいて Bean の追加を開始するよう Spring Boot に指示します。例: spring-webmvc がクラスパスにある場合、このアノテーションはアプリケーションに Web アプリケーションとしてフラグを立て、DispatcherServlet のセットアップなどの主要な動作をアクティブにします。

  • @ComponentScan: Spring に、hello パッケージ内の他のコンポーネント、構成、およびサービスを探して、コントローラーを検出させるように指示します。

main() メソッドは、Spring Boot の SpringApplication.run() メソッドを使用してアプリケーションを起動します。XML が 1 行もないことに気付きましたか? web.xml ファイルもありません。この Web アプリケーションは 100% 純粋な Java であり、接続機能やインフラストラクチャの構成に対処する必要はありませんでした。

@EnableGemfireRepositories アノテーションは、Pivotal GemFire リポジトリの Spring Data をアクティブにし ますPivotal GemFire 用 Spring Data は、PersonRepository インターフェースの具体的な実装を作成し、Pivotal GemFire の埋め込みインスタンスと通信するように構成します。

実行可能 JAR を構築する

コマンドラインから Gradle または Maven を使用してアプリケーションを実行できます。必要なすべての依存関係、クラス、およびリソースを含む単一の実行可能 JAR ファイルを構築して実行することもできます。実行可能な jar を構築すると、開発ライフサイクル全体、さまざまな環境などで、アプリケーションとしてサービスを簡単に提供、バージョン管理、およびデプロイできます。

Gradle を使用する場合、./gradlew bootRun を使用してアプリケーションを実行できます。または、次のように、./gradlew build を使用して JAR ファイルをビルドしてから、JAR ファイルを実行できます。

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

Maven を使用する場合、./mvnw spring-boot:run を使用してアプリケーションを実行できます。または、次のように、./mvnw clean package で JAR ファイルをビルドしてから、JAR ファイルを実行できます。

java -jar target/gs-accessing-gemfire-data-rest-0.1.0.jar
ここで説明する手順は、実行可能な JAR を作成します。クラシック WAR ファイルを作成することもできます。

ロギング出力が表示されます。サービスは数秒以内に起動して実行されるはずです。

アプリケーションをテストする

アプリケーションが実行されたため、テストできます。任意の REST クライアントを使用できます。次の例では、*nix ツール curl を使用しています。

最初に、トップレベルのサービスを見たいです。

$ curl http://localhost:8080
{
  "_links" : {
    "people" : {
      "href" : "http://localhost:8080/people"
    }
  }
}

ここでは、このサーバーが提供するものを初めて垣間見ることができます。http://localhost:8080/people にはのリンクがあります。Spring Data for Pivotal GemFire は、他の Spring Data REST ガイドのようなページネーションをサポートしていないため、余分なナビゲーションリンクはありません。

Spring Data REST は、JSON 出力に HAL フォーマット (英語) を使用します。柔軟性があり、提供されるデータに隣接するリンクを提供する便利な方法を提供します。
$ curl http://localhost:8080/people
{
  "_links" : {
    "search" : {
      "href" : "http://localhost:8080/people/search"
    }
  }
}

新しい Person を作成する時間です!

$ curl -i -X POST -H "Content-Type:application/json" -d '{  "firstName" : "Frodo",  "lastName" : "Baggins" }' http://localhost:8080/people
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Location: http://localhost:8080/people/1
Content-Length: 0
Date: Wed, 05 Mar 2014 20:16:11 GMT
  • -i は、ヘッダーを含むレスポンスメッセージを確認できるようにします。新しく作成された Person の URI が表示されます

  • -X POST は POST HTTP リクエストを発行して新しいエントリを作成する

  • -H "Content-Type:application/json" は content-type を設定し、アプリケーションがペイロードに JSON オブジェクトが含まれていることを認識する

  • -d '{ "firstName" : "Frodo", "lastName" : "Baggins" }' は送信されるデータです

前の POST 操作に Location ヘッダーが含まれていることに注意してください。これには、新しく作成されたリソースの URI が含まれます。Spring Data REST には、RepositoryRestConfiguration.setReturnBodyOnCreate(…) と setReturnBodyOnCreate(…) の 2 つのメソッドがあり、作成したリソースの表現をすぐに返すようにフレームワークを構成するために使用できます。

これから、すべての人を照会できます。

$ curl http://localhost:8080/people
{
  "_links" : {
    "search" : {
      "href" : "http://localhost:8080/people/search"
    }
  },
  "_embedded" : {
    "persons" : [ {
      "firstName" : "Frodo",
      "lastName" : "Baggins",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/people/1"
        }
      }
    } ]
  }
}

人物コレクションリソースには、Frodo のリストが含まれています。自己リンクがどのように含まれているかに注目してください。Spring Data REST はまた、Evo インフレクター (英語) を使用して、グループ化のためにエンティティの名前を複数形にします。

個々のレコードを直接照会できます。

$ curl http://localhost:8080/people/1
{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/people/1"
    }
  }
}
これは純粋に Web ベースのように見えるかもしれませんが、バックグラウンドでは、埋め込まれた Pivotal GemFire データベースと通信しています。

このガイドでは、ドメインオブジェクトは 1 つだけです。ドメインオブジェクトが互いに関連しているより複雑なシステムでは、Spring Data REST は追加のリンクをレンダリングして、接続されたレコードへのナビゲートを支援します。

すべてのカスタムクエリを検索します。

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

HTTP クエリパラメーター name を含むクエリの URL を確認できます。お気づきのように、これはインターフェースに埋め込まれた @Param("name") アノテーションと一致します。

findByLastName クエリを使用するには、次の操作を行います。

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

コードで List<Person> を返すように定義しているため、すべての結果が返されます。Person のみを返すように定義していた場合、Person オブジェクトの 1 つを選択して返します。これは予測できないため、複数のエントリを返す可能性のあるクエリに対してはそうしたくないでしょう。

PUTPATCH および DELETE REST 呼び出しを発行して、既存のレコードを置換、更新、または削除することもできます。

$ curl -X PUT -H "Content-Type:application/json" -d '{ "firstName": "Bilbo", "lastName": "Baggins" }' http://localhost:8080/people/1
$ curl http://localhost:8080/people/1
{
  "firstName" : "Bilbo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/people/1"
    }
  }
}
$ curl -X PATCH -H "Content-Type:application/json" -d '{ "firstName": "Bilbo Jr." }' http://localhost:8080/people/1
$ curl http://localhost:8080/people/1
{
  "firstName" : "Bilbo Jr.",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/people/1"
    }
  }
}
PUT はレコード全体を置き換えます。指定されていないフィールドは null に置き換えられます。PATCH を使用して、アイテムのサブセットを更新できます。

レコードを削除できます:

$ curl -X DELETE http://localhost:8080/people/1
$ curl http://localhost:8080/people
{
  "_links" : {
    "search" : {
      "href" : "http://localhost:8080/people/search"
    }
  }
}

このハイパーメディア駆動型インターフェース (英語) の非常に便利な側面は、curl (または使用している REST クライアント)を使用してすべての REST フルエンドポイントを検出する方法です。正式な契約書やインターフェースドキュメントを顧客と交換する必要はありません。

要約

おめでとう!ハイパーメディアベースRESTful (英語) フロントエンドと Pivotal GemFire ベースのバックエンドを備えたアプリケーションを開発しました。