Please note that the contents of this offline web site may be out of date. To access the most recent documentation visit the online version .
Note that links that point to online resources are green in color and will open in a new window.
We would love it if you could give us feedback about this material by filling this form (You have to be online to fill it)



Getting started with Google Cloud Datastore and Node.js

Before running through the steps below, make sure that:

In order to make API calls to the Datastore, you first need to install google-api-nodejs-client by running the following command:

npm install [email protected]

Then, download and unzip the latest version of the google-cloud-datastore samples:

unzip google-cloud-datastore-1beta2-rev1-2.1.0.zip

If you are not connected to a Compute Engine instance, make sure to run the following commands (in a bash-like shell):

# convert the .p12 private key file to a .pem file
# if asked to enter import password, use "notasecret"
openssl pkcs12 -in <path-to-private-key-file> -out <path-to-pem-file> -nodes -nocerts

# configure your credentials
export DATASTORE_SERVICE_ACCOUNT=<service-account>
export DATASTORE_PRIVATE_KEY_FILE=<path-to-pem-file>

Finally, run the adams.js demo with your <dataset-id> as a parameter. It will prompt for the question and validate your answer.

node google-cloud-datastore-1beta2-rev1-2.1.0/nodejs/demos/trivial/adams.js <dataset-id>
Meaning of life? 11
Don't Panic!

The comments in the sample's source explain its behavior in detail:

var util = require('util');
var events = require('events');
var readline = require('readline');
var googleapis = require('googleapis');

var SCOPES = ['https://www.googleapis.com/auth/userinfo.email',
              'https://www.googleapis.com/auth/datastore'];


/**
 * Adams is a simple command line application using the Datastore API.
 *
 * It writes an entity to the datastore that represents a Trivia
 * question with its answer to your dataset. Does a lookup by key and
 * presents the question to the user. If the user gets the right
 * answer, it will greet him with a quote from a famous book.
 *
 * @param {string} datasetId The ID of the dataset.
 * @constructor
 * @extends {events.EventEmitter}
 */
function Adams(datasetId) {
  this.datasetId = datasetId;
  this.readline = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });
  this.authorize();
}
util.inherits(Adams, events.EventEmitter);


/**
 * Authorize with the Datastore API.
 */
Adams.prototype.authorize = function() {
  // First, try to retrieve credentials from Compute Engine metadata server.
  this.credentials = new googleapis.auth.Compute();
  this.credentials.authorize((function(computeErr) {
    if (computeErr) {
      var errors = {'compute auth error': computeErr};
      // Then, fallback on JWT credentials.
      this.credentials = new googleapis.auth.JWT(
          process.env['DATASTORE_SERVICE_ACCOUNT'],
          process.env['DATASTORE_PRIVATE_KEY_FILE'],
          SCOPES);
      this.credentials.authorize((function(jwtErr) {
        if (jwtErr) {
          errors['jwt auth error'] = jwtErr;
          this.emit('error', errors);
          return;
        }
        this.connect();
      }).bind(this));
    }
  }).bind(this));
};


/**
 * Connect to the Datastore API.
 */
Adams.prototype.connect = function() {
  // Build the API bindings for the current version.
  googleapis.discover('datastore', 'v1beta2')
      .withAuthClient(this.credentials)
      .execute((function(err, client) {
        if (err) {
          this.emit('error', {'connection error': err});
          return;
        }
        // Bind the datastore client to datasetId and get the datasets
        // resource.
        this.datastore = client.datastore.withDefaultParams({
          datasetId: this.datasetId}).datasets;
        this.beginTransaction();
      }).bind(this));
};


/**
 * Start a new transaction.
 */
Adams.prototype.beginTransaction = function() {
  this.datastore.beginTransaction({
    // Execute the RPC asynchronously, and call back with either an
    // error or the RPC result.
  }).execute((function(err, result) {
    if (err) {
      this.emit('error', {'rpc error': err});
      return;
    }
    this.transaction = result.transaction;
    this.lookup();
  }).bind(this));
};


/**
 * Lookup for the Trivia entity.
 */
Adams.prototype.lookup = function() {
  // Get entities by key.
  this.datastore.lookup({
    readOptions: {
      // Set the transaction, so we get a consistent snapshot of the
      // value at the time the transaction started.
      transaction: this.transaction
    },
    // Add one entity key to the lookup request, with only one
    // `path` element (i.e. no parent).
    keys: [{ path: [{ kind: 'Trivia', name: 'hgtg' }] }]
  }).execute((function(err, result) {
    if (err) {
      this.emit('error', {'rpc error': err});
      return;
    }
    // Get the entity from the response if found.
    if (result.found.length > 0) {
      this.entity = result.found[0].entity;
    }
    this.commit();
  }).bind(this));
};


/**
 * Commit the transaction and an insert mutation if the entity was not
 * found.
 */
Adams.prototype.commit = function() {
  if (!this.entity) {
    // If the entity is not found create it.
    this.entity = {
        // Set the entity key with only one `path` element (i.e. no parent).
        key: { path: [{ kind: 'Trivia', name: 'hgtg' }] },
        // Set the entity properties:
        // - a utf-8 string: `question`
        // - a 64bit integer: `answer`
        properties: {
          question: { stringValue: 'Meaning of life?' },
          answer: { integerValue: 42 }
        }
      };
    // Build a mutation to insert the new entity.
    mutation = { insert: [this.entity] };
  } else {
    // No mutation if the entity was found.
    mutation = null;
  }
  // Commit the transaction and the insert mutation if the entity was not found.
  this.datastore.commit({
    transaction: this.transaction,
    mutation: mutation
  }).execute((function(err, result) {
    if (err) {
      this.emit('error', err);
      return;
    }
    this.ask();
  }).bind(this));
};


/**
 * Ask for the question and validate the answer.
 */
Adams.prototype.ask = function() {
  // Get `question` property value.
  var question = this.entity.properties.question.stringValue;
  // Get `answer` property value.
  var answer = this.entity.properties.answer.integerValue;
  // Print the question and read one line from stdin.
  this.readline.question(question + ' ', (function(result) {
    this.readline.close();
    // Validate the input against the entity answer property.
    if (parseInt(result, 10) == answer) {
      console.log('fascinating, extraordinary and, ',
                  'when you think hard about it, completely obvious.');
    } else {
      console.log("Don't panic!");
    }
  }).bind(this));
};


console.assert(process.argv.length == 3, 'usage: trivial.js <dataset-id>');
// Get the dataset ID from the command line parameters.
var demo = new Adams(process.argv[2]);
demo.once('error', function(err) {
  console.error('Adams:', err);
  process.exit(1);
});

With this example, you learned how to use the:

  • googleapis package to connect to the Datastore API.
  • beginTransaction method to start a transaction.
  • lookup method to retrieve entities by key from your dataset.
  • commit method to send mutations to entities in your dataset and commit the transaction.

Now, you are ready to learn more about the Key Datastore Concepts and look at the JSON API reference .

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.