Usar o Cloud Storage com Node.js

Nesta parte do tutorial do Bookshelf em Node.js, veja como as imagens são armazenadas pelo app de amostra no Google Cloud Storage.

Esta página é parte de um tutorial com várias páginas. Para começar do início e ler as instruções de configuração, acesse o app Node.js Bookshelf.

Como criar um intervalo do Cloud Storage

Veja nas instruções a seguir como criar um intervalo do Cloud Storage. Intervalos são os contêineres básicos que armazenam dados no Cloud Storage.

  1. Em uma janela de terminal, digite o seguinte comando:

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

    Em que:

    • [YOUR-BUCKET-NAME] representa o nome do intervalo do Cloud Storage.
  2. Para visualizar imagens carregadas no aplicativo Bookshelf, defina a lista de controle de acesso (ACL, na sigla em inglês) padrão do intervalo como public-read.

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

    Como definir configurações

    Copie o arquivo config.json da seção Dados estruturados deste tutorial para o diretório nodejs-getting-started/3-binary-data. Adicione esta linha ao arquivo copiado:

    "CLOUD_BUCKET": "[YOUR_BUCKET_NAME]"
    

    Substitua [YOUR_BUCKET_NAME] pelo nome do seu intervalo do Cloud Storage.

    Como instalar dependências

    Use npm para instalar as dependências no diretório nodejs-getting-started/3-binary-data:

        npm install
    

    Execução do app na máquina local

    1. Inicie um servidor da Web local usando npm:

          npm start
      
    1. No navegador da Web, digite este endereço:

      http://localhost:8080

    Agora você pode procurar as páginas da Web do app e adicionar, editar e excluir livros.

    Como implantar o app no ambiente padrão do App Engine

    1. Implante o aplicativo de amostra a partir do diretório nodejs-getting-started/3-binary-data:

      gcloud app deploy
      
    2. No navegador da Web, digite este endereço. Substitua [YOUR_PROJECT_ID] pelo seu código do projeto:

      https://[YOUR_PROJECT_ID].appspot.com
      

    Para atualizar o app, implante a versão atualizada digitando o mesmo comando usado para implantá-lo pela primeira vez. A implantação cria uma nova versão do aplicativo e a define como padrão. As versões anteriores do seu app são mantidas. Por padrão, o ambiente do App Engine é escalonado para zero instâncias quando não há tráfego de entrada em uma versão. Portanto, as versões não usadas não serão cobradas. No entanto, todas essas versões de apps ainda são recursos faturáveis.

    Consulte a seção Limpeza na etapa final deste tutorial para ver mais informações sobre a limpeza de recursos faturáveis, incluindo versões de apps não padrão.

    Estrutura do aplicativo

    Exemplo de estrutura de dados binários

    O aplicativo utiliza o Cloud Storage para armazenar dados binários (imagens, nesse caso), mas continua usando um banco de dados estruturado para as informações do livro (Cloud Datastore ou Cloud SQL).

    Como entender o código

    Nesta seção, vamos analisar o código do aplicativo e explicar como ele funciona.

    Como processar uploads do usuário

    Para permitir o upload de imagens, modificamos o formulário de adição/edição para que os usuários possam fazer o upload de arquivos configurando enctype como multipart/form-data. Além disso, há um novo campo no formulário para imagem:

    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

    O aplicativo usa o middleware multer do Express para processar a análise de solicitações de upload de arquivo. Ele armazena os arquivos enviados temporariamente na memória para depois enviá-los direto ao Cloud Storage:

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

    Como fazer o upload para o Google Cloud Storage

    Em seguida, o aplicativo usa o middleware sendUploadToGCS para processar o upload dos arquivos na memória para o 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);
    }

    O middleware faz a verificação de cada arquivo da solicitação e os envia para o Cloud Storage por meio de um streaming gravável padrão. Após o upload, os arquivos se tornam públicos e o middleware define a propriedade cloudStoragePublicUrl no arquivo. Use o URL público para exibir a imagem diretamente do Cloud Storage:

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

    Em seguida, o aplicativo usa essa propriedade para salvar o URL público da imagem no banco de dados:

    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.
        getModel().create(data, (err, savedData) => {
          if (err) {
            next(err);
            return;
          }
          res.redirect(`${req.baseUrl}/${savedData.id}`);
        });
      }
    );

    Como veicular imagens do Cloud Storage

    Como o aplicativo tem o URL público da imagem, a exibição é simples. Vale a pena fazer isso direto do Cloud Storage porque as solicitações usam a infraestrutura de exibição global do Google, e o aplicativo não precisa responder a solicitações de imagens. Isso libera ciclos de CPU para outras solicitações.

    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
Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…