Application Spring Boot avec Cloud Datastore

1. Présentation

Conçue pour le scaling automatique et les hautes performances, Google Cloud Datastore est une base de données de documents NoSQL qui simplifie le développement d'applications.

Points abordés

  • Utiliser Cloud Datastore pour enregistrer et récupérer des objets Java dans Spring Boot

Prérequis

  • Un projet Google Cloud Platform
  • Un navigateur tel que Chrome ou Firefox

Comment allez-vous utiliser ce tutoriel ?

Je vais le lire uniquement Je vais le lire et effectuer les exercices

Quel est votre niveau d'expérience avec les services Google Cloud Platform ?

<ph type="x-smartling-placeholder"></ph> Débutant Intermédiaire Expert
.

2. Préparation

Configuration de l'environnement au rythme de chacun

  1. Connectez-vous à la console Google Cloud, puis créez un projet ou réutilisez un projet existant. (Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.)

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Le nom du projet est le nom à afficher pour les participants au projet. Il s'agit d'une chaîne de caractères non utilisée par les API Google. Vous pourrez toujours la modifier.
  • L'ID du projet est unique parmi tous les projets Google Cloud et non modifiable une fois défini. La console Cloud génère automatiquement une chaîne unique (en général, vous n'y accordez d'importance particulière). Dans la plupart des ateliers de programmation, vous devrez indiquer l'ID de votre projet (généralement identifié par PROJECT_ID). Si l'ID généré ne vous convient pas, vous pouvez en générer un autre de manière aléatoire. Vous pouvez également en spécifier un et voir s'il est disponible. Après cette étape, l'ID n'est plus modifiable et restera donc le même pour toute la durée du projet.
  • Pour information, il existe une troisième valeur (le numéro de projet) que certaines API utilisent. Pour en savoir plus sur ces trois valeurs, consultez la documentation.
  1. Vous devez ensuite activer la facturation dans la console Cloud pour utiliser les ressources/API Cloud. L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Pour désactiver les ressources et éviter ainsi que des frais ne vous soient facturés après ce tutoriel, vous pouvez supprimer le projet ou les ressources que vous avez créées. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai sans frais pour bénéficier d'un crédit de 300 $.

Activer Cloud Shell

  1. Dans Cloud Console, cliquez sur Activer Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Si vous démarrez Cloud Shell pour la première fois, un écran intermédiaire vous explique de quoi il s'agit. Si un écran intermédiaire vous s'est présenté, cliquez sur Continue (Continuer).

9c92662c6a846a5c.png

Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.

9f0e51b578fecce5.png

Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute dans Google Cloud, ce qui améliore considérablement les performances du réseau et l'authentification. Une grande partie, voire la totalité, de votre travail dans cet atelier de programmation peut être effectué dans un navigateur.

Une fois connecté à Cloud Shell, vous êtes authentifié et le projet est défini sur votre ID de projet.

  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list

Résultat de la commande

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet:
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Si vous obtenez un résultat différent, exécutez cette commande :

gcloud config set project <PROJECT_ID>

Résultat de la commande

Updated property [core/project].

3. Initialiser Cloud Datastore

Dans la console GCP, accédez à Menu -> Datastore (dans la section "Stockage") ou cliquez ici.

Si vous n'avez jamais utilisé Datastore dans le projet actuel, l'écran Sélectionner un mode Cloud Firestore s'affiche. Sélectionnez l'option Mode Datastore.

f938295c7ff297f4.png

L'écran Choisissez où stocker vos données s'affiche alors. Sélectionnez us-east1 ou tout autre emplacement régional, puis cliquez sur "Créer une base de données" :

916ac84fec10fae7.png

4. Amorcer une nouvelle application Java Spring Boot

Dans l'environnement Cloud Shell, utilisez la commande suivante pour initialiser et amorcer une nouvelle application 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 -

Cette opération crée un répertoire datastore-example/ avec un nouveau projet Maven, ainsi que le pom.xml de Maven, un wrapper Maven et un point d'entrée d'application.

Notre application fournit une CLI permettant aux utilisateurs de saisir des commandes et de voir les résultats. Nous allons créer une classe pour représenter un livre, puis l'enregistrer dans Cloud Datastore à l'aide d'un dépôt Datastore.

Nous devons également ajouter une autre dépendance nécessaire à pom.xml.

Ouvrez l'éditeur de code Web en cliquant sur Ouvrir l'éditeur dans le menu Cloud Shell.

6d823258c76a7452.png

Une fois l'éditeur chargé, modifiez le fichier pom.xml pour ajouter les dépendances Google Cloud Datastore Starter et 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. Créer la classe Livre

À l'aide de l'éditeur, créez la classe Book avec le contenu suivant:

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 +
        '}';
  }
}

Comme vous pouvez le voir, il s'agit d'un simple POJO. La classe est annotée avec @Entity pour indiquer qu'elle peut être stockée dans Datastore et fournir le nom de genre (imaginez un genre comme une table dans des bases de données SQL, consultez la documentation pour en savoir plus). Le nom de genre est facultatif. S'il est omis, le nom de genre sera généré à partir du nom de la classe.

Notez que nous avons annoté la propriété id avec @Id. Cela indique que nous souhaitons utiliser ce champ en tant que partie identifiant de la clé Datastore. Chaque entité Datastore a besoin d'un identifiant. Les types acceptés sont String et Long.

Nous remplaçons la méthode toString pour rendre la représentation sous forme de chaîne des objets plus lisible. cela sera utile lorsque nous les imprimerons.

6. Créer l'interface BookRepository

Créez la classe BookRepository avec le contenu suivant:

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

L'interface étend DatastoreRepository<Book, Long>, où Book est la classe de domaine et Long est le type Id. Nous déclarons trois méthodes de requête dans notre dépôt, pour lesquelles des implémentations sont générées automatiquement en arrière-plan.

Le premier est findByAuthor. Comme vous pouvez le deviner, l'implémentation de cette méthode exécutera une requête qui utilisera une valeur fournie par l'utilisateur dans le filtre de condition pour le champ d'égalité à l'auteur.

La méthode findByYearGreaterThan exécute une requête qui filtre le champ d'année supérieur à la valeur fournie par l'utilisateur.

findByAuthorAndYear exécute une requête qui recherche les entités dans lesquelles les champs "author" et "year" correspondent aux valeurs fournies par l'utilisateur.

7. Créer l'application CLI interactive

Ouvrez la classe DemoApplication de l'application principale et modifiez-la comme suit:

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();
  }
}

Notez comment nous avons annoté la classe avec @ShellComponent. Cela indique à Spring que nous voulons utiliser cette classe comme source pour les commandes CLI. Les méthodes annotées avec @ShellMethod seront exposées en tant que commandes CLI dans notre application.

Nous utilisons ici les méthodes que nous avons déclarées dans l'interface BookRepository: findByAuthor, findByYearGreaterThan et findByAuthorAndYear. Nous utilisons également trois méthodes intégrées: save, findAll et deleteAll.

Examinons la méthode saveBook. Nous créons un objet Book en utilisant les valeurs fournies par l'utilisateur pour le titre, l'auteur et l'année. Comme vous pouvez le voir, nous ne fournissons pas de valeur id. Elle sera donc automatiquement allouée et attribuée au champ id lors de l'enregistrement. La méthode save accepte un objet de type Book et l'enregistre dans Cloud Datastore. Elle renvoie un objet Book avec tous les champs renseignés, y compris le champ id. À la fin, nous renvoyons une représentation de cet objet sous forme de chaîne.

Les autres méthodes fonctionnent de la même manière: elles acceptent les paramètres transmis aux méthodes de dépôt appropriées et renvoient des résultats concaténés.

8. Exécuter l'application

Pour compiler et démarrer l'application, assurez-vous d'abord que JAVA_HOME est défini sur la bonne version:

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

Exécutez la commande suivante dans Cloud Shell (à partir de la racine du projet datastore-example/ où se trouve pom.xml):

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

Après une étape de compilation réussie, le logo Spring s'affiche et l'invite de shell s'affiche:

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



shell:>

Vous pouvez maintenant tester les commandes que nous avons définies précédemment. Pour afficher la liste des commandes, utilisez la commande help:

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>

Essayez d'exécuter les commandes suivantes :

  1. Créez quelques livres avec la commande save-book
  2. Exécuter une recherche à l'aide de la commande find-all-books
  3. Rechercher les livres d'un auteur spécifique: find-by-author <author>
  4. Rechercher les livres publiés après une année spécifique: find-by-year-after <year>
  5. Rechercher les livres par auteur et année spécifiques: find-by-author-year <author> <year>

9. Afficher les éléments stockés dans Datastore à l'aide de l'interface Web

Pour voir comment les entités sont stockées dans Cloud Datastore, accédez à la console GCP. Saisir "livres" dans le champ "kind", si nécessaire.

5fab21a6c89f45a.png

10. Effectuer un nettoyage

Pour effectuer un nettoyage, supprimez tous les livres à l'aide de la commande remove-all-books correctement nommée dans le shell de l'application.

shell:> remove-all-books

Pour quitter l'application, utilisez la commande quitt, puis Ctrl+C.

11. Félicitations !

Dans cet atelier de programmation, vous avez créé une application CLI interactive capable de stocker et de récupérer des objets depuis Cloud Datastore.

En savoir plus

Licence

Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.