Using Cloud Spanner with Cloud Functions

Cloud Spanner

Objectives

This topic demonstrates writing, deploying, and triggering an HTTP Cloud Function that accesses Cloud Spanner.

Costs

This topic uses Cloud Spanner, Google Cloud Storage, and Google Cloud Functions, which are billable components of the Google Cloud Platform.

Before you begin

  1. This topic assumes you have a Cloud Spanner instance named test-instance and a database named example-db that uses the music application schema. For instructions on creating an instance and database with the music application schema, see Quickstart Using the Console or the tutorials for Getting Started in Go, Java, Node.js, or Python.

  2. Enable the Cloud Functions API.
    Enable the Cloud Functions API

  3. Install and initialize the Cloud SDK.

  4. Update and install gcloud components:

    gcloud components update &&
    gcloud components install beta
    

  5. Prepare your environment for Node.js development.

Prepare the application

  1. Create a Cloud Storage bucket to stage your Cloud Functions files, where [BUCKET_NAME] is a globally-unique bucket name:

    gsutil mb gs://[BUCKET_NAME]
    

  2. Clone the sample app repository to your local machine:

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
    

    Alternatively, you can download the sample as a zip file and extract it.

  3. Change to the directory that contains the Cloud Functions sample code for accessing Cloud Spanner:

    cd nodejs-docs-samples/functions/spanner/
    
  4. Take a look at the sample index.js file.

    Node.js

    // Imports the Google Cloud client library
    const Spanner = require('@google-cloud/spanner');
    
    // Instantiates a client
    const spanner = Spanner();
    
    // Your Cloud Spanner instance ID
    const instanceId = 'test-instance';
    
    // Your Cloud Spanner database ID
    const databaseId = 'example-db';
    
    /**
     * HTTP Cloud Function.
     *
     * @param {Object} req Cloud Function request context.
     * @param {Object} res Cloud Function response context.
     */
    exports.get = (req, res) => {
      // Gets a reference to a Cloud Spanner instance and database
      const instance = spanner.instance(instanceId);
      const database = instance.database(databaseId);
    
      // The query to execute
      const query = {
        sql: 'SELECT * FROM Albums'
      };
    
      // Execute the query
      return database.run(query)
        .then((results) => {
          const rows = results[0].map((row) => row.toJSON());
          rows.forEach((row) => {
            res.write(`SingerId: ${row.SingerId.value}, AlbumId: ${row.AlbumId.value}, AlbumTitle: ${row.AlbumTitle}\n`);
          });
          res
            .status(200)
            .end();
        })
        .catch((err) => {
          res
            .status(500)
            .send(`Error querying Spanner: ${err}`)
            .end();
        });
    };

    The get function sends a SQL query to fetch all Albums data from your database. The get function is exported by the module and is executed when you make an HTTP request to the function's endpoint.

Deploy a function

To deploy the get function with an HTTP trigger, run the following command in the gcf_spanner directory:

gcloud beta functions deploy get --stage-bucket [BUCKET_NAME] --trigger-http

where [BUCKET_NAME] is the name of your Cloud Storage bucket.

Function deployment may take up to 2 minutes. You should see output similar to the following when the function is deployed:

availableMemoryMb: 256
entryPoint: get
httpsTrigger:
  url: https://[REGION]-[PROJECT_ID].cloudfunctions.net/get
latestOperation: operations/Y29kZS1wdXJwbGUvdXMtY2VudHJhbDEvaGVsbG9HRVQvdGJkYjdWTl9SUWc
name: projects/[PROJECT_ID]/locations/us-central1/functions/get
serviceAccount: [PROJECT_ID]@appspot.gserviceaccount.com
sourceArchiveUrl: gs://[BUCKET]/us-central1-get-cxegebv.zip
status: READY
timeout: 60s
updateTime: '2017-04-28T23:37:15Z'

Note the url value returned when your function finishes deploying. You will use it when you trigger the function.

You can view your deployed functions on the Cloud Functions page in the Google Cloud Platform Console. You can also create and edit functions on that page, and get details and diagnostics for your functions.

Trigger the function

Make an HTTP request to your function:

curl "https://[REGION]-[PROJECT_ID].cloudfunctions.net/get"

where [REGION] and [PROJECT_ID] match the values that are visible in your terminal when your function finishes deploying. You should see output that shows the results of the SQL query, assuming you worked through a Getting Started tutorial and populated the database:

SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold Your Peace
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk

You can also visit the function's endpoint in your browser to see the result of your SQL query. Enter the following in your browser:

https://[REGION]-[PROJECT_ID].cloudfunctions.net/get

Cleanup

To avoid incurring additional charges to your Cloud Platform account for the Cloud Spanner, Cloud Functions, and Cloud Storage resources used in this topic:

  1. Delete the instance:

    gcloud spanner instances delete test-instance
    
  2. Delete the function that you deployed:

    gcloud beta functions delete get
    

  3. Delete the storage bucket:

    gsutil rm -r gs://[BUCKET_NAME]
    

What's next

Monitor your resources on the go

Get the Google Cloud Console app to help you manage your projects.

Send feedback about...

Cloud Functions Documentation