Cloud Storage mit Node.js verwenden

In diesem Teil der Node.js-Bookshelf-Anleitung wird gezeigt, wie die Beispielanwendung Bilder in Cloud Storage speichert.

Diese Seite ist Teil einer mehrseitigen Anleitung. Rufen Sie die Node.js Bookshelf-Anwendung auf, um die Dokumentation von Anfang an durchzugehen und Anleitungen zur Einrichtung zu erhalten.

Cloud Storage-Bucket erstellen

In der folgenden Anleitung wird im Detail erläutert, wie Sie einen Cloud Storage-Bucket erstellen. Buckets sind die grundlegenden Container für Ihre Daten in Cloud Storage.

  1. Erstellen Sie in Ihrem Terminalfenster einen Cloud Storage-Bucket, wobei YOUR_BUCKET_NAME für den Namen Ihres Buckets steht:

    gsutil mb gs://YOUR_BUCKET_NAME
    
  2. Legen Sie für die standardmäßige Access Control List (ACL) des Buckets public-read fest, damit hochgeladene Bilder in der Bookshelf-Anwendung angezeigt werden.

    gsutil defacl set public-read gs://YOUR_BUCKET_NAME
    

Einstellungen konfigurieren

Erstellen Sie im Verzeichnis nodejs-getting-started/3-binary-data eine config.json-Datei mit folgendem Inhalt:

{
  "CLOUD_BUCKET": "[YOUR_BUCKET_NAME]"
}

Ersetzen Sie dabei [YOUR_BUCKET_NAME] durch den Namen des Cloud Storage-Buckets.

Abhängigkeiten installieren

Verwenden Sie npm, um Abhängigkeiten im Verzeichnis nodejs-getting-started/3-binary-data zu installieren:

npm install

Anwendung auf dem lokalen Computer ausführen

  1. Starten Sie einen lokalen Webserver mithilfe von npm:

    npm start
    
  2. Geben Sie im Webbrowser die folgende Adresse ein:

    http://localhost:8080

Sie können jetzt auf den Webseiten der Anwendung stöbern, Bücher mit Titelbildern hinzufügen sowie Bücher bearbeiten und löschen.

Anwendung in der App Engine-Standardumgebung bereitstellen

  1. Stellen Sie die Beispielanwendung aus dem Verzeichnis nodejs-getting-started/3-binary-data bereit:

    gcloud app deploy
    
  2. Geben Sie im Webbrowser folgende Adresse ein:

    https://[YOUR_PROJECT_ID].appspot.com
    

    Ersetzen Sie [YOUR_PROJECT_ID] durch Ihre Google Cloud-Projekt-ID.

Wenn Sie die Anwendung aktualisieren, stellen Sie die aktualisierte Version bereit. Dazu geben Sie den gleichen Befehl ein, den Sie bei der ersten Bereitstellung der Anwendung verwendet haben. Bei der neuen Bereitstellung wird eine neue Version der Anwendung erstellt und zur Standardversion hochgestuft. Die älteren Versionen der Anwendung werden beibehalten. Standardmäßig wird die App Engine-Standardumgebung auf 0 Instanzen skaliert, wenn kein Traffic bei einer Version eingeht. Daher sollten nicht verwendete Versionen keine Kosten verursachen. Alle diese Anwendungsversionen bleiben jedoch kostenpflichtige Ressourcen.

Weitere Informationen zur Bereinigung abrechenbarer Ressourcen, einschließlich der Anwendungsversionen, die keine Standardversionen sind, finden Sie im Abschnitt Bereinigen im letzten Schritt dieser Anleitung.

Anwendungsstruktur

Beispielstruktur für Binärdaten

Die Anwendung verwendet Cloud Storage zum Speichern von Binärdaten, in diesem Fall von Bildern. Für die Buchinformationen wird weiterhin eine strukturierte Datenbank verwendet (entweder Datastore oder Cloud SQL).

Den Code verstehen

In diesem Abschnitt werden der Anwendungscode und dessen Funktionsweise erläutert.

Nutzeruploads handhaben

Damit Nutzer Bilder hochladen können, müssen Sie das Formular zum Hinzufügen/Bearbeiten so ändern, dass Dateien hochgeladen werden können. Legen Sie enctype auf multipart/form-data fest und fügen Sie ein Feld für das Bild hinzu:

block content
  h3 #{action} book
  form(method="POST", enctype="multipart/form-data")
    .form-group
      label(for="title") Title
      input.form-control(type="text", name="title", id="title", value=book.title)
    .form-group
      label(for="author") Author
      input.form-control(type="text", name="author", id="author", value=book.author)
    .form-group
      label(for="publishedDate") Date Published
      input.form-control(type="text", name="publishedDate", id="publishedDate", value=book.publishedDate)
    .form-group
      label(for="description") Description
      input.form-control(type="text", name="description", id="description", value=book.description)
    .form-group
      label(for="image") Cover Image
      input.form-control(type="file", name="image", id="image")
    .form-group.hidden
      label(for="imageUrl") Cover Image URL
      input.form-control(type="text", name="imageUrl", id="imageUrl", value=book.imageUrl)
    button.btn.btn-success(type="submit") Save

Die Anwendung verwendet die Middleware Multer für das Parsen von Dateiuploadanfragen. Die Anwendung speichert die hochgeladenen Dateien vorübergehend im Arbeitsspeicher, da diese direkt in Cloud Storage hochgeladen werden:

const Multer = require('multer');
const multer = Multer({
  storage: Multer.MemoryStorage,
  limits: {
    fileSize: 5 * 1024 * 1024, // no larger than 5mb
  },
});

Nach Cloud Storage hochladen

Als Nächstes verwendet die Anwendung die Middleware sendUploadToGCS für das Hochladen der arbeitsspeicherinternen Dateien in Cloud Storage:

function sendUploadToGCS(req, res, next) {
  if (!req.file) {
    return next();
  }

  const gcsname = Date.now() + req.file.originalname;
  const file = bucket.file(gcsname);

  const stream = file.createWriteStream({
    metadata: {
      contentType: req.file.mimetype,
    },
    resumable: false,
  });

  stream.on('error', err => {
    req.file.cloudStorageError = err;
    next(err);
  });

  stream.on('finish', () => {
    req.file.cloudStorageObject = gcsname;
    file.makePublic().then(() => {
      req.file.cloudStoragePublicUrl = getPublicUrl(gcsname);
      next();
    });
  });

  stream.end(req.file.buffer);
}

Die Middleware prüft jede Datei in der Anfrage und lädt sie über einen standardmäßigen schreibbaren Stream in Cloud Storage hoch. Nach dem Hochladen werden die Dateien veröffentlicht und die Middleware legt das Attribut cloudStoragePublicUrl für die Datei fest. Die öffentliche URL stellt das Bild direkt aus Cloud Storage bereit:

function getPublicUrl(filename) {
  return `https://storage.googleapis.com/${CLOUD_BUCKET}/${filename}`;
}

Die Anwendung verwendet dann das folgende Attribut, um die öffentliche URL des Bildes in der Datenbank zu speichern:

router.post(
  '/add',
  images.multer.single('image'),
  images.sendUploadToGCS,
  (req, res, next) => {
    let data = req.body;

    // Was an image uploaded? If so, we'll use its public URL
    // in cloud storage.
    if (req.file && req.file.cloudStoragePublicUrl) {
      data.imageUrl = req.file.cloudStoragePublicUrl;
    }

    // Save the data to the database.
    model.create(data, (err, savedData) => {
      if (err) {
        next(err);
        return;
      }
      res.redirect(`${req.baseUrl}/${savedData.id}`);
    });
  }
);

Bilder aus Cloud Storage bereitstellen

Da die Anwendung die öffentliche URL des Bildes kennt, lässt sich das Bild ganz einfach bereitstellen. Die direkte Bereitstellung über Cloud Storage ist hilfreich, da die Anfragen die globale Bereitstellungsinfrastruktur von Google nutzen. Die Anwendung muss nicht auf Bildanfragen antworten, wodurch CPU-Zyklen für andere Anfragen freigegeben werden.

block content
  h3 Book
    small

  .btn-group
    a(href=`/books/${book.id}/edit`, class='btn btn-primary btn-sm')
      i.glyphicon.glyphicon-edit
      span  Edit book
    a(href=`/books/${book.id}/delete`, class='btn btn-danger btn-sm')
      i.glyphicon.glyphicon-trash
      span  Delete book

  .media
    .media-left
      img(src=book.imageUrl || "http://placekitten.com/g/128/192")
    .media-body
      h4= book.title
        |  
        small= book.publishedDate
      h5 By #{book.author||'unknown'}
      p= book.description
Hat Ihnen diese Seite weitergeholfen? Teilen Sie uns Ihr Feedback mit:

Feedback geben zu...