How to call the Home Graph API with gRPC on Node.js

588 Views Asked by At

Given the protocol buffers definition available at: https://github.com/googleapis/googleapis/blob/master/google/home/graph/v1/homegraph.proto

How can one call the Home Graph API RPC endpoint using gRPC on Node.js to multiplex concurrent API method calls over a single connection?

1

There are 1 best solutions below

0
On BEST ANSWER

You can use @grpc-js in combination with Application Default Credentials to initialize the credentials.

$ npm install @grpc/grpc-js
$ npm install google-auth-library
$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json
const grpc = require('@grpc/grpc-js');
const { GoogleAuth } = require('google-auth-library');

async function getCredentials() {
  const sslCredentials = grpc.credentials.createSsl();
  const googleAuth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/homegraph'
  });
  const authClient = await googleAuth.getClient();
  const callCredentials = grpc.credentials.createFromGoogleCredential(
      authClient
  );
  const credentials = grpc.credentials.combineChannelCredentials(
      sslCredentials,
      callCredentials
  );
  return credentials;
}

Use google-proto-files with @grpc/proto-loader to load the Home Graph service protobuf definition with its dependencies.

const protoLoader = require('@grpc/proto-loader');
const protos = require('google-proto-files');

async function getHomegraph() {
  const homegraphProto = await protoLoader.load(
      protos.getProtoPath('home/graph', 'v1', 'homegraph.proto'), {
        includeDirs: [protos.getProtoPath('..')]
      }
  );
  const homegraph = grpc.loadPackageDefinition(
      homegraphProto
  ).google.home.graph.v1;
  return homegraph;
}

And finally initialize client stubs to call the HomeGraphApiService methods.

(async function() {
  const credentials = await getCredentials();
  const homegraph = await getHomegraph();

  const homegraphService = new homegraph.HomeGraphApiService(
      'homegraph.googleapis.com', credentials
  );

  homegraphService.sync({
    agentUserId: 'AGENT_USER_ID'
  }, function(err, result) {
    if (err) {
      console.error(err);
    } else {
      console.log(result);
    }
  });

  // homegraphService.query();
  // homegraphService.requestSyncDevices();
  // homegraphService.reportStateAndNotification();
  // homegraphService.deleteAgentUser();
})();

Note that by default the Channel implementation will reuse existing channels from a global pool if the parameters (address, credentials and options) are the same. You can alter this behavior with the grpc.use_local_subchannel_pool option.