Aplicación Spring Boot con Cloud Datastore

1. Descripción general

Google Cloud Datastore es una base de datos de documentos NoSQL creada para proporcionar ajuste de escala automático, alto rendimiento y facilidad de desarrollo de aplicaciones.

Qué aprenderás

  • Cómo usar Cloud Datastore para guardar y recuperar objetos Java en Spring Boot

Requisitos

  • Un proyecto de Google Cloud Platform
  • Un navegador, como Chrome o Firefox

¿Cómo usarás este instructivo?

Ler Leer y completar los ejercicios

¿Cómo calificarías tu experiencia en el uso de los servicios de Google Cloud Platform?

Principiante Intermedio Avanzado .
.

2. Configuración y requisitos

Configuración del entorno de autoaprendizaje

  1. Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una cadena de caracteres que no se utiliza en las APIs de Google. Puedes actualizarla cuando quieras.
  • El ID del proyecto es único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). La consola de Cloud genera automáticamente una cadena única. Por lo general, no importa cuál sea. En la mayoría de los codelabs, deberás hacer referencia al ID de tu proyecto (suele identificarse como PROJECT_ID). Si no te gusta el ID que se generó, podrías generar otro aleatorio. También puedes probar uno propio y ver si está disponible. No se puede cambiar después de este paso y se usa el mismo durante todo el proyecto.
  • Recuerda que hay un tercer valor, un número de proyecto, que usan algunas APIs. Obtén más información sobre estos tres valores en la documentación.
  1. A continuación, deberás habilitar la facturación en la consola de Cloud para usar las APIs o los recursos de Cloud. Ejecutar este codelab no costará mucho, tal vez nada. Para cerrar recursos y evitar que se generen cobros más allá de este instructivo, puedes borrar los recursos que creaste o borrar el proyecto. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de $300.

Activar Cloud Shell

  1. En la consola de Cloud, haz clic en Activar Cloud Shell853e55310c205094.png.

55efc1aaa7a4d3ad.png

Si es la primera vez que inicias Cloud Shell, verás una pantalla intermedia que describe en qué consiste. Si apareció una pantalla intermedia, haz clic en Continuar.

9c92662c6a846a5c.png

El aprovisionamiento y la conexión a Cloud Shell solo tomará unos minutos.

9f0e51b578fecce5.png

Esta máquina virtual está cargada con todas las herramientas de desarrollo necesarias. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que mejora considerablemente el rendimiento de la red y la autenticación. Gran parte de tu trabajo en este codelab, si no todo, se puede hacer con un navegador.

Una vez que te conectes a Cloud Shell, deberías ver que estás autenticado y que el proyecto está configurado con tu ID del proyecto.

  1. En Cloud Shell, ejecuta el siguiente comando para confirmar que tienes la autenticación:
gcloud auth list

Resultado del comando

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Ejecuta el siguiente comando en Cloud Shell para confirmar que el comando de gcloud conoce tu proyecto:
gcloud config list project

Resultado del comando

[core]
project = <PROJECT_ID>

De lo contrario, puedes configurarlo con el siguiente comando:

gcloud config set project <PROJECT_ID>

Resultado del comando

Updated property [core/project].

3. Inicializar Cloud Datastore

En la consola de Google Cloud, navega a Menú -> Datastore (en la sección Storage) o haz clic aquí.

Si nunca usaste Datastore en el proyecto actual, verás la pantalla “Seleccionar un modo de Cloud Firestore”. Selecciona la opción "Modo Datastore".

f938295c7ff297f4.png

Luego, aparecerá la pantalla "Elige dónde almacenar tus datos". Seleccione us-east1 o cualquier otra ubicación regional y haga clic en "Crear base de datos":

916ac84fec10fae7.png

4. Inicia una nueva aplicación de Java de Spring Boot

Desde el entorno de Cloud Shell, usa el siguiente comando para inicializar e iniciar una nueva aplicación de 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 -

Esto creará un directorio datastore-example/ nuevo con un proyecto de Maven nuevo, junto con el pom.xml de Maven, un wrapper de Maven y un punto de entrada de la aplicación.

Nuestra aplicación proporcionará una CLI para que los usuarios ingresen comandos y vean resultados. Crearemos una clase para representar un libro y lo guardaremos en Cloud Datastore mediante el repositorio de Datastore.

También necesitamos agregar una dependencia más necesaria a pom.xml.

Haz clic en Abrir editor en el menú de Cloud Shell para abrir el editor de código web.

6d823258c76a7452.png

Después de que se cargue el editor, modifica el archivo pom.xml para agregar las dependencias de Google Cloud Datastore Starter y 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. Crea la clase Book

Con el editor, crea la clase Book con el siguiente contenido:

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

Como puedes ver, se trata de un POJO simple. La clase está anotada con @Entity para indicar que se puede almacenar en Datastore y proporcionar el nombre del tipo (piensa en un tipo como una tabla en bases de datos SQL; consulta la documentación para obtener más detalles). El nombre de la categoría es opcional. Si se omite, el nombre de la categoría se generará según el nombre de la clase.

Ten en cuenta que anotamos la propiedad id con @Id. Eso indica que queremos que este campo se use como la parte del identificador de la clave de Datastore. Cada entidad de Datastore necesita un identificador. Los tipos admitidos son String y Long.

Anulamos el método toString para que la representación de cadena de los objetos sea más legible. esto será útil cuando los imprimamos.

6. Crea la interfaz de BookRepository

Crea la clase BookRepository con el siguiente contenido:

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

La interfaz extiende DatastoreRepository<Book, Long>, en el que Book es la clase de dominio y Long es el tipo Id. Declaramos tres métodos de consulta en nuestro repositorio para los cuales las implementaciones se generan automáticamente en segundo plano.

El primero es findByAuthor. Como puedes suponer, la implementación de este método ejecutará una consulta que usará un valor proporcionado por el usuario en el filtro de condición para el campo de igualdad al autor.

El método findByYearGreaterThan ejecuta una consulta que filtra por el campo de año mayor que el valor proporcionado por el usuario.

findByAuthorAndYear ejecuta una consulta que busca entidades en las que los campos de autor y año coincidan con los valores proporcionados por el usuario.

7. Crea la aplicación interactiva de la CLI

Abre la clase DemoApplication principal de la aplicación y modifícala para que se vea de la siguiente manera:

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

Observa cómo anotamos la clase con @ShellComponent. Esto le indica a Spring que queremos usar esta clase como fuente para los comandos de la CLI. Los métodos anotados con @ShellMethod se expondrán como comandos de la CLI en nuestra aplicación.

Aquí, usamos los métodos que declaramos en la interfaz BookRepository: findByAuthor, findByYearGreaterThan y findByAuthorAndYear. También usamos tres métodos integrados: save, findAll y deleteAll.

Veamos el método saveBook. Creamos un objeto Book con los valores de título, autor y año que proporciona el usuario. Como puedes ver, no proporcionamos un valor id, por lo que se asignará automáticamente al campo id cuando se guarde. El método save acepta un objeto de tipo Book y lo guarda en Cloud Datastore. Muestra un objeto Book con todos los campos propagados, incluido el campo id. Al final, se muestra una representación de cadena de este objeto.

El resto de los métodos funcionan de manera similar: aceptan parámetros pasados a los métodos de repositorio apropiados y muestran resultados en cadena.

8. Ejecuta la aplicación

Para compilar e iniciar la aplicación, primero asegúrate de que JAVA_HOME esté configurado en la versión correcta:

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

Ejecuta este comando en Cloud Shell (desde la raíz del proyecto datastore-example/, en la que se encuentra pom.xml):

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

Después de una etapa de compilación exitosa, se mostrará el logotipo de Spring y aparecerá el mensaje de shell:

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



shell:>

Ahora puedes experimentar con los comandos que definimos anteriormente. Para ver la lista de comandos, usa el comando 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>

Prueba lo siguiente:

  1. Crea algunos libros con el comando save-book
  2. Ejecuta una búsqueda con el comando find-all-books
  3. Buscar libros por autor específico: find-by-author <author>
  4. Buscar libros publicados después de un año específico: find-by-year-after <year>
  5. Buscar libros por autor y año específicos: find-by-author-year <author> <year>

9. Consulta qué se almacena en Datastore con la interfaz web

Para ver cómo se almacenan las entidades en Cloud Datastore, ve a GCP Console. Ingresar "libros" en el campo Kind, si es necesario.

5fab21a6c89f45a.png

10. Limpia

Para realizar una limpieza, quita todos los libros usando el comando remove-all-books bien llamado del shell de la aplicación.

shell:> remove-all-books

Para salir de la aplicación, usa el comando quit y, luego, Ctrl+C.

11. ¡Felicitaciones!

En este codelab, creaste una aplicación interactiva de la CLI que puede almacenar y recuperar objetos de Cloud Datastore.

Más información

Licencia

Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.