Cómo usar Cloud Storage con Go

Esta sección del instructivo de Bookshelf para Go muestra cómo la aplicación de muestra almacena imágenes en Cloud Storage. Para el uso general de Cloud Storage con Go, consulta la documentación de las bibliotecas cliente de Cloud Storage.

Esta página forma parte de un instructivo de varias páginas. Para comenzar desde el principio y leer las instrucciones de configuración, visita la app de Bookshelf para Go.

Cómo crear un depósito de Cloud Storage

Las instrucciones siguientes muestran cómo crear un depósito de Cloud Storage. Los depósitos son los contenedores básicos que conservan tus datos en Cloud Storage.

  1. Ingresa el siguiente comando en una ventana de la terminal:

    gsutil mb gs://[YOUR-BUCKET-NAME]

    Donde:

    • [YOUR-BUCKET-NAME] representa el nombre de tu depósito de Cloud Storage.
  2. Para ver las imágenes que se subieron en la app de Bookshelf, configura la lista de control de acceso (LCA) predeterminada del depósito como public-read.

    gsutil defacl set public-read gs://[YOUR-BUCKET-NAME]

    Configuraciones

    1. Ve al directorio que contiene el código de muestra:

      Linux/macOS

      cd $GOPATH/src/github.com/GoogleCloudPlatform/golang-samples/getting-started/bookshelf
      

      Windows

      cd %GOPATH%\src\github.com\GoogleCloudPlatform\golang-samples\getting-started\bookshelf
      

    2. Abre config.go para editar.

    3. Borra los comentarios de estas líneas:

      // StorageBucketName = "<your-storage-bucket>"
      // StorageBucket, err = configureStorage(StorageBucketName)
      
    4. Reemplaza <your-storage-bucket> por el nombre de tu depósito de Cloud Storage.

    5. Guarda y cierra config.go.

    Cómo ejecutar la app en la máquina local

    1. Ejecuta la app para iniciar un servidor web local:

      cd app
      go run app.go auth.go template.go
      
    2. En el navegador web, ingresa la siguiente dirección:

      http://localhost:8080

    Ahora puedes navegar por las páginas web de la app y agregar libros con imágenes de portada, así como editar y borrar libros.

    Presiona Control + C para salir del servidor web local.

    Cómo implementar la app en el entorno flexible de App Engine

    1. En el directorio app, ingresa el siguiente comando para implementar la muestra:

      gcloud app deploy
      
    2. En el navegador web, ingresa la siguiente dirección. Reemplaza [YOUR_PROJECT_ID] por el ID del proyecto:

      https://[YOUR_PROJECT_ID].appspot.com
      

    Si actualizas tu app, podrás implementar la versión actualizada mediante el mismo comando que usaste para implementar la app por primera vez. La implementación nueva crea una versión nueva de tu app y la convierte a la versión predeterminada. Las versiones anteriores de la app se conservan, al igual que sus instancias de VM asociadas. Ten en cuenta que todas estas instancias de VM y versiones de la app son recursos facturables.

    Para reducir costos, borra las versiones no predeterminadas de la app.

    Para borrar una versión de una app, haz lo siguiente:

    1. En GCP Console, dirígete a la página Versiones de App Engine.

      Ir a la página de Versiones

    2. Haz clic en la casilla de verificación junto a la versión de app no predeterminada que deseas borrar.
    3. Haz clic en el botón Borrar en la parte superior de la página para borrar la versión de la app.

    Para obtener toda la información acerca de la limpieza de los recursos facturables, consulta la sección Limpieza en el paso final de este instructivo.

    Estructura de la aplicación

    Estructura de muestra de datos binarios

    La aplicación usa Cloud Storage para almacenar datos binarios (en este caso, imágenes), mientras continúa usando una base de datos estructurada para la información de los libros, ya sea Cloud Datastore, Cloud SQL o MongoDB.

    Cómo comprender el código

    En esta sección se explica el código de la aplicación y su funcionamiento.

    Cómo manejar las cargas de los usuarios

    Para permitir que los usuarios carguen imágenes, el formulario de agregar/editar configura enctype en multipart/form-data. Las etiquetas de acción de la plantilla especifican el destino de la solicitud HTTP POST. Para un libro nuevo, que no tiene un ID, el destino es /books. Para un libro existente, es /books/$ID:

    <form method="post" enctype="multipart/form-data" action="/books{{if .}}/{{.ID}}{{end}}">

    El campo image acepta un archivo como entrada:

    <div class="form-group">
      <label for="image">Cover Image</label>
      <input class="form-control" name="image" id="image" type="file">
    </div>

    Cómo subir archivos a Cloud Storage

    La función uploadFileFromForm verifica si el campo del formulario image está presente, y si lo está, carga el archivo a Cloud Storage. Finalmente, la función devuelve la URL pública del archivo cargado.

    // uploadFileFromForm uploads a file if it's present in the "image" form field.
    func uploadFileFromForm(r *http.Request) (url string, err error) {
    	f, fh, err := r.FormFile("image")
    	if err == http.ErrMissingFile {
    		return "", nil
    	}
    	if err != nil {
    		return "", err
    	}
    
    	if bookshelf.StorageBucket == nil {
    		return "", errors.New("storage bucket is missing - check config.go")
    	}
    
    	// random filename, retaining existing extension.
    	name := uuid.Must(uuid.NewV4()).String() + path.Ext(fh.Filename)
    
    	ctx := context.Background()
    	w := bookshelf.StorageBucket.Object(name).NewWriter(ctx)
    
    	// Warning: storage.AllUsers gives public read access to anyone.
    	w.ACL = []storage.ACLRule{{Entity: storage.AllUsers, Role: storage.RoleReader}}
    	w.ContentType = fh.Header.Get("Content-Type")
    
    	// Entries are immutable, be aggressive about caching (1 day).
    	w.CacheControl = "public, max-age=86400"
    
    	if _, err := io.Copy(w, f); err != nil {
    		return "", err
    	}
    	if err := w.Close(); err != nil {
    		return "", err
    	}
    
    	const publicURL = "https://storage.googleapis.com/%s/%s"
    	return fmt.Sprintf(publicURL, bookshelf.StorageBucketName, name), nil
    }

    bookFromForm llama a la función uploadFileFromForm, la cual extrae todos los valores de formulario esperados en una estructura Book. La función bookFromForm almacena la URL pública de la imagen en la base de datos como una string.

    // bookFromForm populates the fields of a Book from form values
    // (see templates/edit.html).
    func bookFromForm(r *http.Request) (*bookshelf.Book, error) {
    	imageURL, err := uploadFileFromForm(r)
    	if err != nil {
    		return nil, fmt.Errorf("could not upload file: %v", err)
    	}
    	if imageURL == "" {
    		imageURL = r.FormValue("imageURL")
    	}
    
    	book := &bookshelf.Book{
    		Title:         r.FormValue("title"),
    		Author:        r.FormValue("author"),
    		PublishedDate: r.FormValue("publishedDate"),
    		ImageURL:      imageURL,
    		Description:   r.FormValue("description"),
    		CreatedBy:     r.FormValue("createdBy"),
    		CreatedByID:   r.FormValue("createdByID"),
    	}

    Cómo publicar imágenes desde Cloud Storage

    Dado que tenemos la URL pública de la imagen, publicarla es simple. Publicarla directamente desde Cloud Storage es útil, ya que las solicitudes aprovechan la infraestructura de publicación global de Google y no es necesario que la aplicación responda a las solicitudes de imágenes, lo que libera ciclos de CPU para otras solicitudes.

    <img src="{{if .ImageURL}}{{.ImageURL}}{{else}}https://placekitten.com/g/200/300{{end}}">
¿Te ha resultado útil esta página? Enviar comentarios: