Introduction

Google cloud storage is a service that enables you to store object in the cloud. But wait what is object? Simply object is a file be it a pdf, image, zip or anything else. Any kind of file that stored in the cloud will be called object.

And just like a file system in your operating system, you could also create a folder to group the files. In the operating system your file and folder are stored on a disk, disk are equivalent to a bucket in the google cloud storage.

Prerequisite

  1. Make sure NodeJS installed on your system
  2. Register a google cloud account

Diving In

Setup GCS Bucket

  1. If this is the first time you open google cloud, you need to create a project first.

  2. Assuming that you have your google cloud project, open the cloud console and open the left navigation menu. look for storage.

    image-20210526163005502

    In the cloud storage menu click Browse

  3. On the Cloud Storage page, click on Create Bucket in the top of the menu.

    image-20210526173506842

  4. Next create the bucket, follow the steps provided and if you wanted to keep your storage free, make sure that you pick the right region. Here is the free tier information from google cloud.

image-20210526175937205

image-20210526180309771

For the storage class, just pick Standard it suite our current use case, next for the access control pick Uniform. And in the optional setting just leave it as it is. After you click finish the bucket creation process. You should get something like this.

image-20210526182139062

Manually Upload File To Bucket

In this section we will explore some basic of GCS, it is optional. You could skip to the code part if you wanted to.

  1. To upload a file manually to gcs, first click the Upload Files button.

    image-20210526182251763

  2. Then simply pick the file that you wanted to upload, after you finish uploading the file you upload should appear on the bucket as seen below.

    image-20210526182352673

  3. You could open the uploaded file details

    image-20210526182441952

    It will display an Authenticated URL This url is an endpoint where we can acess our file, currently the files are only available to authenticated user. If you tried to access it with unauthenticated user it will give you error.

    image-20210526182637354

    1. To enable public sharing, go to the google cloud storage dashboard and click on Permissions

      image-20210526182723947

    2. Click on Add then create the following permission.

      image-20210526182948075

      This permission will enable any user to see our files even if they are not authenticated. if you wanted to give access to only the authenticated user you could use allAuthenticatedUsers instead. you will be prompted about giving public access to the bucket, press Allow Public Access.

      image-20210526183129553

      If you go to your object information again, you will have 2 kind of url public and authenticated.

      image-20210526183528017

      Now anyone can access the file from the public url.

NodeJS, ExpressJS and GCS

In this section we will create a web server using express and nodejs with an endpoint that upload file to the gcs.

  1. Create a folder and do npm init

    image-20210526185257379

    You could use npm init --y to skip all the configuration and leave it default.

  2. Install the dependencies

    npm i --save express @google-cloud/storage multer
    
  3. Create index.js on the root of your project. Here we will initiate our express project and utilize multer middleware.

    const express = require('express')
    const multer = require('multer')
          
    const app = express()
          
    const multerMid = multer({
      storage: multer.memoryStorage(),
      limits: {
        fileSize: 5 * 1024 * 1024,
      },
    })
          
    app.use(multerMid.single('file'))
    app.use(express.json())
    app.use(express.urlencoded({extended: false}))
          
    app.post('/uploads', async (req, res, next) => {
        res.send("Uploads")
    })
          
    app.use((err, req, res, next) => {
        res.status(500).json({
          error: err,
          message: 'Internal server error!',
        })
        next()
      })
          
    app.listen(3030, () => {
      console.log(`Listening at port ${3030}`)
    })
    

    You could run the code using node index.js then try to request to localhost:3030/uploads you should get this return

    image-20210526191802004

  4. Next step is to setup google cloud service. first in the search bar on top look for API & Services.

    image-20210526193258959

    Scroll down and look for Cloud Storage

    image-20210526193342009

    If the API is disabled, you should enable it first. to setup our service credential open the Credentials menu on the left bar.

    image-20210526193453863

    Then create a service account credentials.

    image-20210526193528033

    Fill in the required information. then press create

    image-20210526193644992

    Create a new role and assign it as Cloud Storage -> Storage Admin

    image-20210526193950078

    Press next and click done. Back in the API & Services dashboard you should find the new service account.

    image-20210526194235420

    Click on the newly created Service Account, then goto Keys and Add Key

    image-20210526194327479

    Create the key in JSON format and click Create.

    image-20210526194356962

    Now you should be prompted with a dialog box to save the service account credential, create a folder in the project root called config and save the credential there.

    image-20210526194608066

    Next step is to utilize the credential, in the config folder create a index.js and write the following.

    const Cloud = require("@google-cloud/storage")
    const path = require('path')
    const serviceKey = path.join(__dirname, './<path-to-credential.json>')
          
    const {Storage} = Cloud
          
    const storage = new Storage({
        keyFilename : serviceKey,
        projectId : '<project id>'
    })
          
    module.exports = storage
    

    Do not forget to change the credential path and also the projectId.

    After credential is setup, we need to create an upload helper. Create a helpers in the root of your project and then create helpers.js inside. So far your project structure should look something like this.

    image-20210526200344197

    Write the following code in helpers.js

    const util = require('util')
    const gc = require('../config')
    const bucket = gc.bucket('<your-bucket-name>')
          
    exports.uploadImage = (file) => new Promise((resolve, reject)=>{
        const {originalname, buffer} = file
          
        const blob = bucket.file(originalname.replace(/ /g, "_"))
        const blobStream = blob.createWriteStream({
            resumable: false
        })
          
        blobStream.on('finish', ()=> {
            const publicUrl = util.format(
                `https://storage.googleapis.com/${bucket.name}/${blob.name}`
            )
          
            resolve(publicUrl)
        }).on('error', (err)=> {
            console.log(err)
            reject(`Unable to upload iamge, something went wrong`)
        })
        .end(buffer)
    })
    

    Do not forgot to replace the bucket name with your bucket.

    Require the uploadImage() that we recently create in index.js

    const { uploadImage } = require('./helpers/helpers')
    

    Finally we just need to update our /uploads endpoint into.

    app.post('/uploads', async (req, res, next) => {
      try{
        const myFile = req.file
        const imageUrl = await uploadImage(myFile)
        res.status(200).json({
            message : "Upload succeed",
            daat : imageUrl
        })
      }catch(err){
        next(err)
      }
    })
    

    To run the app simply use

    node index.js
    

    You could nodemon to make the development process easier.

Testing the Endpoint

To test the upload, run the app.

image-20210526200653095

If you are using postman, you could try this request.

image-20210526200802465

If everything is working correctly, you should get this return.

image-20210526200945113

Now if you acces the url using private browser, you should be able to receive and see the image.

image-20210526201029971

And it is done! Thankyou you so much for reading the article and i hope this small article could help you! If you have any question you could ask it in the disqus comment section or directly message me in instagram or twitter @arifluthfi16. See you in the next one!

Here is some parrot.

60fpsparrot

Source Codes

Here is the link to source code, please note that i remove the credential config. So it will not work instantly when you run it.

https://github.com/arifluthfi16/blog-gcs