Cloud Datastore を使用した Spring Boot アプリケーション

1. 概要

Google Cloud Datastore は、自動スケーリングと高パフォーマンスを実現し、アプリケーション開発を簡素化するように構築された NoSQL ドキュメント データベースです。

学習内容

  • Cloud Datastore を使用して Spring Boot で Java オブジェクトを保存して取得する方法

必要なもの

  • Google Cloud Platform プロジェクト
  • ブラウザ(ChromeFirefox など)

このチュートリアルの利用方法をお選びください。

通読するのみ 通読し、演習を行う

Google Cloud Platform サービスのご利用経験についてどのように評価されますか?

初心者 中級者 上級者

2. 設定と要件

セルフペース型の環境設定

  1. Google Cloud Console にログインして、プロジェクトを新規作成するか、既存のプロジェクトを再利用します。Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください。

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • プロジェクト名は、このプロジェクトの参加者に表示される名称です。Google API では使用されない文字列です。いつでも更新できます。
  • プロジェクト ID は、すべての Google Cloud プロジェクトにおいて一意でなければならず、不変です(設定後は変更できません)。Cloud コンソールでは一意の文字列が自動生成されます。通常は、この内容を意識する必要はありません。ほとんどの Codelab では、プロジェクト ID(通常は PROJECT_ID と識別されます)を参照する必要があります。生成された ID が好みではない場合は、ランダムに別の ID を生成できます。または、ご自身で試して、利用可能かどうかを確認することもできます。このステップ以降は変更できず、プロジェクトを通して同じ ID になります。
  • なお、3 つ目の値として、一部の API が使用するプロジェクト番号があります。これら 3 つの値について詳しくは、こちらのドキュメントをご覧ください。
  1. 次に、Cloud のリソースや API を使用するために、Cloud コンソールで課金を有効にする必要があります。この Codelab の操作をすべて行って、費用が生じたとしても、少額です。このチュートリアルの終了後に請求が発生しないようにリソースをシャットダウンするには、作成したリソースを削除するか、プロジェクトを削除します。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。

Cloud Shell をアクティブにする

  1. Cloud Console で、[Cloud Shell をアクティブにする] 853e55310c205094.png をクリックします。

55efc1aaa7a4d3ad.png

Cloud Shell を初めて起動する場合は、その内容を説明する中間画面が表示されます。中間画面が表示された場合は、[続行] をクリックします。

9c92662c6a846a5c.png

すぐにプロビジョニングが実行され、Cloud Shell に接続されます。

9f0e51b578fecce5.png

この仮想マシンには、必要な開発ツールがすべて用意されています。仮想マシンは Google Cloud で稼働し、永続的なホーム ディレクトリが 5 GB 用意されているため、ネットワークのパフォーマンスと認証が大幅に向上しています。このコードラボで行う作業のほとんどはブラウザから実行できます。

Cloud Shell に接続すると、認証が完了しており、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。

  1. Cloud Shell で次のコマンドを実行して、認証されたことを確認します。
gcloud auth list

コマンド出力

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Cloud Shell で次のコマンドを実行して、gcloud コマンドがプロジェクトを認識していることを確認します。
gcloud config list project

コマンド出力

[core]
project = <PROJECT_ID>

上記のようになっていない場合は、次のコマンドで設定できます。

gcloud config set project <PROJECT_ID>

コマンド出力

Updated property [core/project].

3. Cloud Datastore を初期化する

GCP Console で、[メニュー] -> [Datastore]([ストレージ] セクション)に移動するか、こちらをクリックします。

現在のプロジェクトで Datastore を使用したことがない場合は、[Cloud Firestore モードを選択] 画面が表示されます。[Datastore モード] オプションを選択します。

f938295c7ff297f4.png

その後、[データの保存場所を選択] 画面が表示されます。[us-east1] またはその他のリージョン ロケーションを選択して、[データベースを作成] をクリックします。

916ac84fec10fae7.png

4. 新しい Spring Boot Java アプリケーションをブートストラップする

CloudShell 環境から次のコマンドを使用して、新しい Spring Boot アプリケーションを初期化およびブートストラップします。

$ curl https://start.spring.io/starter.tgz \
  -d packaging=war \
  -d dependencies=cloud-gcp \
  -d type=maven-project \
  -d baseDir=datastore-example \
  -d bootVersion=3.0.5 | tar -xzvf -

これにより、Maven の pom.xml、Maven ラッパー、アプリケーションのエントリポイントとともに、新しい Maven プロジェクトを含む新しい datastore-example/ ディレクトリが作成されます。

このアプリケーションは、ユーザーがコマンドを入力して結果を確認するための CLI を提供します。書籍を表すクラスを作成し、Datastore リポジトリを使用して Cloud Datastore に保存します。

また、pom.xml に必要な依存関係をもう 1 つ追加する必要があります。

Cloud Shell メニューの [エディタを開く] をクリックして、ウェブ コードエディタを開きます。

6d823258c76a7452.png

エディタが読み込まれたら、pom.xml ファイルを変更して、Google Cloud Datastore Starter と Spring Shell Starter の依存関係を追加します。

pom.xml

<project>
  ...
  <dependencies>
        ...
        <!-- Add GCP Datastore Starter -->
        <dependency>
                <groupId>com.google.cloud</groupId>
                <artifactId>spring-cloud-gcp-starter-data-datastore</artifactId>
        </dependency>

        <!-- Add Spring Shell Starter -->
        <dependency>
                <groupId>org.springframework.shell</groupId>
                <artifactId>spring-shell-starter</artifactId>
                <version>3.0.2</version>
        </dependency>

  </dependencies>
</project>

5. Book クラスを作成する

エディタを使用して、次の内容で Book クラスを作成します。

datastore-example/src/main/java/com/example/demo/Book.java

package com.example.demo;

import com.google.cloud.spring.data.datastore.core.mapping.Entity;
import org.springframework.data.annotation.Id;

@Entity(name = "books")
public class Book {
  @Id
  Long id;

  String title;

  String author;

  int year;

  public Book(String title, String author, int year) {
    this.title = title;
    this.author = author;
    this.year = year;
  }

  public long getId() {
    return this.id;
  }

  @Override
  public String toString() {
    return "Book{" +
        "id=" + this.id +
        ", title='" + this.title + '\'' +
        ", author='" + this.author + '\'' +
        ", year=" + this.year +
        '}';
  }
}

ご覧のとおり、これはシンプルな POJO です。クラスには @Entity アノテーションが付けられています。これは、クラスを Datastore に保存できることと、種類名(SQL データベースのテーブルのようなもの。詳しくはドキュメントを参照)を提供することを示します。種類名は省略可能です。省略すると、種類名はクラス名に基づいて生成されます。

id プロパティに @Id アノテーションを付けたことに注意してください。これは、このフィールドを Datastore キーの識別子部分として使用することを意味します。すべての Datastore エンティティには識別子が必要です。サポートされるタイプは StringLong です。

toString メソッドをオーバーライドして、オブジェクトの文字列表現を読みやすくします。これは、オブジェクトを出力するときに役立ちます。

6. BookRepository インターフェースを作成します。

次の内容で BookRepository クラスを作成します。

datastore-example/src/main/java/com/example/demo/BookRepository.java

package com.example.demo;

import java.util.List;

import com.google.cloud.spring.data.datastore.repository.DatastoreRepository;


public interface BookRepository extends DatastoreRepository<Book, Long> {

  List<Book> findByAuthor(String author);

  List<Book> findByYearGreaterThan(int year);

  List<Book> findByAuthorAndYear(String author, int year);
}

インターフェースは DatastoreRepository<Book, Long> を拡張します。ここで、Book はドメインクラス、LongId 型です。リポジトリで 3 つのクエリ メソッドを宣言します。これらのメソッドの実装は、バックグラウンドで自動的に生成されます。

1 つ目は findByAuthor です。このメソッドの実装では、ユーザーが指定した値を条件フィルタで使用して、作成者フィールドとの等価性をチェックするクエリが実行されます。

findByYearGreaterThan メソッドは、ユーザーが指定した値より大きい year フィールドをフィルタするクエリを実行します。

findByAuthorAndYear は、著者フィールドと年フィールドがユーザーが指定した値と一致するエンティティを探すクエリを実行します。

7. インタラクティブな CLI アプリケーションを作成する

メイン アプリケーションの DemoApplication クラスを開き、次のように変更します。

datastore-example/src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;

import java.util.List;

import com.google.common.collect.Lists;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;

@ShellComponent
@SpringBootApplication
public class DemoApplication {
  @Autowired
  BookRepository bookRepository;

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

  @ShellMethod("Saves a book to Cloud Datastore: save-book <title> <author> <year>")
  public String saveBook(String title, String author, int year) {
     Book savedBook = this.bookRepository.save(new Book(title, author, year));
     return savedBook.toString();
  }

  @ShellMethod("Loads all books")
  public String findAllBooks() {
     Iterable<Book> books = this.bookRepository.findAll();
     return Lists.newArrayList(books).toString();
  }

  @ShellMethod("Loads books by author: find-by-author <author>")
  public String findByAuthor(String author) {
     List<Book> books = this.bookRepository.findByAuthor(author);
     return books.toString();
  }

  @ShellMethod("Loads books published after a given year: find-by-year-after <year>")
  public String findByYearAfter(int year) {
     List<Book> books = this.bookRepository.findByYearGreaterThan(year);
     return books.toString();
  }

  @ShellMethod("Loads books by author and year: find-by-author-year <author> <year>")
  public String findByAuthorYear(String author, int year) {
     List<Book> books = this.bookRepository.findByAuthorAndYear(author, year);
     return books.toString();
  }

  @ShellMethod("Removes all books")
  public void removeAllBooks() {
     this.bookRepository.deleteAll();
  }
}

クラスに @ShellComponent アノテーションを付けたことに注目してください。これにより、このクラスを CLI コマンドのソースとして使用することを Spring に通知します。@ShellMethod アノテーションが付いたメソッドは、アプリケーションで CLI コマンドとして公開されます。

ここでは、BookRepository インターフェースで宣言したメソッド(findByAuthorfindByYearGreaterThanfindByAuthorAndYear)を使用します。また、savefindAlldeleteAll の 3 つの組み込みメソッドも使用します。

saveBook メソッドを見てみましょう。タイトル、著者、年についてユーザーが指定した値を使用して Book オブジェクトを作成します。ご覧のとおり、id の値は指定されていません。そのため、保存時に自動的に割り当てられ、id フィールドに割り当てられます。save メソッドは Book 型のオブジェクトを受け取り、Cloud Datastore に保存します。id フィールドを含むすべてのフィールドに値が設定された Book オブジェクトが返されます。最後に、このオブジェクトの文字列表現を返します。

残りのメソッドも同様に機能します。渡されたパラメータを適切なリポジトリ メソッドに渡し、文字列化された結果を返します。

8. アプリケーションを実行する

アプリケーションをビルドして起動するには、まず JAVA_HOME が正しいバージョンに設定されていることを確認します。

$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Cloud Shell で次のコマンドを実行します(pom.xml があるプロジェクト datastore-example/ のルートから)。

$ ./mvnw spring-boot:run
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

ビルド ステージが成功すると、spring ロゴが表示され、シェル プロンプトが表示されます。

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.5)



shell:>

これで、先ほど定義したコマンドを試すことができます。コマンドのリストを表示するには、ヘルプ コマンドを使用します。

shell:> help
...
find-all-books: Loads all books
find-by-author: Loads books by author: find-by-author <author>
find-by-author-year: Loads books by author and year: find-by-author-year <author> <year>
find-by-year-after: Loads books published after a given year: find-by-year-after <year>
remove-all-books: Removes all books
save-book: Saves a book to Cloud Datastore: save-book <title> <author> <year>

次のようにしてください。

  1. save-book コマンドを使用して書籍をいくつか作成する
  2. find-all-books コマンドを使用して検索を実行する
  3. 特定の著者の書籍を検索する: find-by-author <author>
  4. 特定の年以降に出版された書籍を検索する: find-by-year-after <year>
  5. 特定の著者と年で書籍を検索する: find-by-author-year <author> <year>

9. ウェブ インターフェースを使用して Datastore に保存されている内容を確認する

エンティティが Cloud Datastore にどのように保存されているかを確認するには、GCP Console に移動します。必要に応じて、kind フィールドに「books」と入力します。

5fab21a6c89f45a.png

10. クリーンアップ

クリーンアップするには、アプリケーション シェルから remove-all-books コマンドを使用してすべての書籍を削除します。

shell:> remove-all-books

アプリケーションを終了するには、quit コマンドを入力して Ctrl+C を押します。

11. 完了

この Codelab では、Cloud Datastore からオブジェクトを保存して取得できるインタラクティブな CLI アプリケーションを作成しました。

詳細

ライセンス

この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。