Usar Cloud Firestore en modo Datastore

Firestore es una base de datos de documentos NoSQL creada a fin de proporcionar ajuste de escala automático, alto rendimiento y facilidad para el desarrollo de aplicaciones. Es la versión más reciente de Datastore y presenta varias mejoras con respecto a Datastore.

Debido a que Firestore en modo Datastore está optimizado para los casos de uso del servidor y para App Engine, recomendamos usar Firestore en modo Datastore para las bases de datos que las apps de App Engine usarán en gran medida. Firestore en modo nativo es más útil para casos de uso de notificaciones móviles y en tiempo real. Para obtener más información sobre los modos de Firestore, consulta Elige entre el modo nativo y el modo Datastore.

En este documento, se describe cómo usar la biblioteca cliente de Google Cloud para almacenar y recuperar datos en una base de datos en modo Datastore.

Requisitos previos y configuración

Sigue las instrucciones en “Hello, World!” para Go en App Engine a fin de configurar tu entorno y proyecto, y entender cómo se estructuran las aplicaciones de Go en App Engine. Anota y guarda el ID del proyecto, ya que lo necesitarás para ejecutar la aplicación de muestra que se describe en este documento.

Clona el repositorio

Descarga (clona) la muestra:

go get -d -v github.com/GoogleCloudPlatform/golang-samples/datastore
cd $GOPATH/src/github.com/GoogleCloudPlatform/golang-samples/appengine_flexible/datastore

Edita la configuración del proyecto y ajusta las dependencias

En app.yaml, configura GCLOUD_DATASET_ID para tu proyecto. Este valor es el ID del proyecto.

# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

runtime: go
env: flex

automatic_scaling:
  min_num_instances: 1

env_variables:
  GCLOUD_DATASET_ID: your-project-id

Código de la aplicación

La aplicación de muestra registra, recupera y muestra las IP de los visitantes. Puedes ver que una entrada de registro es una clase simple de dos campos que recibe el tipo visit y se guarda en modo Datastore mediante el comando put del cliente de Datastore. Luego, se recuperan las diez visitas más recientes en orden descendente con los comandos NewQuery y GetAll del cliente de Datastore.


// Sample datastore demonstrates use of the cloud.google.com/go/datastore package from App Engine flexible.
package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"time"

	"cloud.google.com/go/datastore"
	"google.golang.org/appengine"
)

var datastoreClient *datastore.Client

func main() {
	ctx := context.Background()

	// Set this in app.yaml when running in production.
	projectID := os.Getenv("GCLOUD_DATASET_ID")

	var err error
	datastoreClient, err = datastore.NewClient(ctx, projectID)
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/", handle)
	appengine.Main()
}

func handle(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/" {
		http.NotFound(w, r)
		return
	}

	ctx := context.Background()

	// Get a list of the most recent visits.
	visits, err := queryVisits(ctx, 10)
	if err != nil {
		msg := fmt.Sprintf("Could not get recent visits: %v", err)
		http.Error(w, msg, http.StatusInternalServerError)
		return
	}

	// Record this visit.
	if err := recordVisit(ctx, time.Now(), r.RemoteAddr); err != nil {
		msg := fmt.Sprintf("Could not save visit: %v", err)
		http.Error(w, msg, http.StatusInternalServerError)
		return
	}

	fmt.Fprintln(w, "Previous visits:")
	for _, v := range visits {
		fmt.Fprintf(w, "[%s] %s\n", v.Timestamp, v.UserIP)
	}
	fmt.Fprintln(w, "\nSuccessfully stored an entry of the current request.")
}

type visit struct {
	Timestamp time.Time
	UserIP    string
}

func recordVisit(ctx context.Context, now time.Time, userIP string) error {
	v := &visit{
		Timestamp: now,
		UserIP:    userIP,
	}

	k := datastore.IncompleteKey("Visit", nil)

	_, err := datastoreClient.Put(ctx, k, v)
	return err
}

func queryVisits(ctx context.Context, limit int64) ([]*visit, error) {
	// Print out previous visits.
	q := datastore.NewQuery("Visit").
		Order("-Timestamp").
		Limit(10)

	visits := make([]*visit, 0)
	_, err := datastoreClient.GetAll(ctx, q, &visits)
	return visits, err
}

Usa archivos index.yaml

La app de muestra realiza consultas sencillas. Las consultas más elaboradas del modo Datastore requieren uno o más índices, que debes especificar en un archivo index.yaml que tienes que subir junto con la app. Este archivo puede crearse de forma manual o generarse de forma automática mientras se prueba la app de forma local.

Pruebas locales

Si necesitas desarrollar y probar tu aplicación de forma local, puedes usar el emulador del modo Datastore.

Más información

Para obtener toda la información sobre el modo Datastore, incluidos los conceptos y las optimizaciones, consulta la documentación de Firestore en modo Datastore.