Google Cloud Datastore

Getting started with Google Cloud Datastore and Ruby/JSON

Before running through the steps below, make sure that:

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

rvm use 2.0.0
gem install google-api-client

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

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

Make sure to run the following commands (in a bash-like shell):

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

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

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

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

require 'rubygems'
require 'json'
require 'google/api_client'

if ARGV.empty?
  abort "usage: adams.rb <dataset-id>"
end

client = Google::APIClient.new(
  :application_name => 'adams-ruby',
  :application_version => '1.0.0')
# Build the datastore API client.
datastore = client.discovered_api('datastore', 'v1beta2')

# Get the dataset id from command line argument.
dataset_id = ARGV[0]
# Get the credentials from the environment.
service_account = ENV['DATASTORE_SERVICE_ACCOUNT']
private_key_file = ENV['DATASTORE_PRIVATE_KEY_FILE']

# Load the private key from the .p12 file.
private_key = Google::APIClient::KeyUtils.load_from_pkcs12(private_key_file,
                                                           'notasecret')
# Set authorization scopes and credentials.
client.authorization = Signet::OAuth2::Client.new(
  :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
  :audience => 'https://accounts.google.com/o/oauth2/token',
  :scope => ['https://www.googleapis.com/auth/datastore',
             'https://www.googleapis.com/auth/userinfo.email'],
  :issuer => service_account,
  :signing_key => private_key)
# Authorize the client.
client.authorization.fetch_access_token!

# Start a new transaction.
resp = client.execute(
  :api_method => datastore.datasets.begin_transaction,
  :parameters => {:datasetId => dataset_id},
  :body_object => {})

# Get the transaction handle
tx = Base64.encode64(resp.data.transaction)

# Get the entity by key.
resp = client.execute(
  :api_method => datastore.datasets.lookup,
  :parameters => {:datasetId => dataset_id},
  :body_object => {
    # Set the transaction, so we get a consistent snapshot of the
    # value at the time the transaction started.
    :readOptions => {:transaction => tx},
    # Add one entity key to the lookup request, with only one
    # :path element (i.e. no parent)
    :keys => [{:path => [{:kind => 'Trivia', :name => 'hgtg42'}]}]
  })

if not resp.data.found.empty?
  # Get the entity from the response if found.
  entity = resp.data.found[0].entity
  # Get `question` property value.
  question = entity.properties.question.stringValue
  # Get `answer` property value.
  answer = entity.properties.answer.integerValue
  # No mutation.
  mutation = nil
else
  question = 'Meaning of life?'
  answer = 42
  # If the entity is not found create it.
  entity = {
    # Set the entity key with only one `path` element: no parent.
    :key => {
      :path => [{:kind => 'Trivia', :name => 'hgtg42'}]
    },
    # Set the entity properties:
    # - a utf-8 string: `question`
    # - a 64bit integer: `answer`
    :properties => {
      :question => {:stringValue => question},
      :answer => {:integerValue => answer},
    }
  }
  # Build a mutation to insert the new entity.
  mutation = {:insert => [entity]}
end

# Commit the transaction and the insert mutation if the entity was not found.
client.execute(
  :api_method => datastore.datasets.commit,
  :parameters => {:datasetId => dataset_id},
  :body_object => {
    :transaction => tx,
    :mutation => mutation
  })

# Print the question and read one line from stdin.
puts question
result = STDIN.gets.chomp
# Validate the input against the entity answer property.
if result == answer.to_s
  puts ("Fascinating, extraordinary and, when you think hard about it, " +
        "completely obvious.")
else
  puts "Don't Panic!"
end

With this example, you learned how to use the:

  • google-api-client gem to connect to the Datastore API.
  • begin_transaction 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.