Google Cloud Platform 支持包 (gcloud)

gcloud 软件包提供了一个高级的“地道 Dart 风格”接口,用于访问
一些最广泛使用的 Google Cloud Platform 服务。目前
支持以下服务:

  • Cloud Datastore
  • Cloud Storage
  • Cloud Pub/Sub

此软件包中的所有 API 都基于
googleapisgoogleapis_beta 软件包中通用的、自动生成的 API。

这意味着使用此软件包中 API 的身份验证模型
使用的是 googleapis_auth 软件包。

请注意,此软件包仅适用于在服务器或命令行应用程序中
与独立的虚拟机(VM)一起使用。不要期望此软件包能在
浏览器上运行。

下面演示此软件包用法的代码片段都假设
已存在以下导入:

import 'package:googleapis_auth/auth_io.dart' as auth;
import 'package:http/http.dart' as http;
import 'package:gcloud/db.dart';
import 'package:gcloud/storage.dart';
import 'package:gcloud/pubsub.dart';
import 'package:gcloud/service_scope.dart' as ss;
import 'package:gcloud/src/datastore_impl.dart';

获取 API 访问权限

使用 API 的第一步是获取一个经过身份验证的 HTTP 客户端,
并用它创建用于访问不同 API 的 API 类实例。下面的
代码假设你有一个名为 my-project 的 Google Cloud 项目,
并且该项目的服务账户凭据存储在文件
my-project.json 中。.

// Read the service account credentials from the file.
var jsonCredentials = new File('my-project.json').readAsStringSync();
var credentials = new auth.ServiceAccountCredentials.fromJson(jsonCredentials);

// Get an HTTP authenticated client using the service account credentials.
var scopes = []
    ..addAll(dastore_impl.DatastoreImpl.SCOPES);
    ..addAll(Storage.SCOPES)
    ..addAll(PubSub.SCOPES)
var client = await auth.clientViaServiceAccount(creds, scopes);

// Instantiate objects to access Cloud Datastore, Cloud Storage
// and Cloud Pub/Sub APIs.
var db = new DatastoreDB(
    new dastore_impl.DatastoreImpl(client, 's~my-project'));
var storage = new Storage(client, 'my-project');
var pubsub = new PubSub(client, 'my-project');

此软件包中的所有 API 都支持使用“服务作用域”(service scopes)。服务
作用域的详细说明如下。

ss.fork(() {
  // register the services in the new service scope.
  registerDbService(db);
  registerStorageService(storage);
  registerPubSubService(pubsub);
  
  // Run application using these services.
});

在服务作用域中注册的服务,现在可以通过
以下 getter 从在同一服务作用域内运行的所有代码中访问。

dbService.
storageService.
pubsubService.

这样,就不需要在代码中到处传递服务对象了。

与 App Engine 一起使用

gcloud 软件包也已集成到 Dart 的 appengine 软件包中。这
意味着 gcloud 服务可以通过 appengine 上下文和
服务作用域来使用。访问 Google Cloud Platform 服务所需的身份验证
会被自动处理。

这意味着可以通过以下任一方式访问 App Engine Datastore:
通过 App Engine 上下文

var db = context.services.db;

或者直接使用服务作用域注册。

var db = dbService;

Cloud Datastore

Google Cloud Datastore 提供了一个 NoSQL、无模式的数据库,用于存储
非关系型数据。请参阅产品页面
https://cloud.google.com/datastore/ 获取更多信息。

Cloud Datastore API 提供了将 Dart 对象映射到 Datastore 中存储的实体
的功能。以下示例展示了如何为一个类添加注解,
使其可以存储实例到 Datastore 中。

@db.Kind()
class Person extends db.Model {
  @db.StringProperty()
  String name;

  @db.IntProperty()
  int age;
}

Kind 注解表明这个类的实例可以被存储。该
类还必须继承自 Model。现在要将一个对象存储到
Datastore,需要创建一个实例并使用 commit 函数。

var person = new Person()
    ..name = ''
    ..age = 42;
await db.commit(inserts: [person]);

函数 query 用于构建一个 Query 对象,可以运行该对象来
执行查询。

var persons = (await db.query(Person).run()).toList();

注意:此软件包包含一个通过 Datastore 类提供的底层 API,
DatastoreDB API 是在此之上构建的。这个额外
API 层的主要原因是为了弥合 App Engine 内部和
通过公共 REST API 暴露的不同 API 之间的差距。我们保留
随时修改甚至移除这个额外层的权利。

Cloud Storage

Google Cloud Storage 提供了一个高可用的对象存储(也称为 BLOB
存储)。请参阅产品页面 https://cloud.google.com/storage/
了解更多信息。

在 Cloud Storage 中,对象(BLOBs)被组织在 *存储桶*(buckets)中。每个存储桶
都有一个全局唯一的名称。以下代码创建了一个名为
my-bucket 的新存储桶,并将文件 my-file.txt 的内容写入到
名为 my-object 的对象中。

var bucket = await storage.createBucket('my-bucket');
new File('my-file.txt').openRead().pipe(bucket.write('my-object'));

以下代码将读回该对象。

bucket.read('my-object').pipe(new File('my-file-copy.txt').openWrite());

Cloud Pub/Sub

Google Cloud Pub/Sub 提供了多对多的异步消息传递服务。请参阅
产品页面 https://cloud.google.com/pubsub/ 获取更多信息。

Cloud Pub/Sub 使用两个概念进行消息传递。如果你想发送消息,可以使用 *主题*(Topics);
如果你想订阅主题并接收消息,可以使用 *订阅*(subscriptions)。
这实现了消息生产者与消息消费者的
解耦。

以下代码创建了一个 *主题* 并发送一条简单的测试消息:

var topic = await pubsub.createTopic('my'topic');
await topic.publishString('Hello, world!')

通过以下代码,在 *主题* 上创建了一个 *订阅*,并
使用该订阅拉取一条消息。消费者处理完接收到的消息后,必须
对其进行确认。

var subscription =
    await pubsub.createSubscription('my-subscription', 'my-topic);
var pullEvent = await subscription.pull();
print(pullEvent.message.asString);
await pullEvent.acknowledge()

也可以使用推送事件来接收消息,而不是从
订阅中拉取。为此,订阅应配置为
带有 HTTP 端点的推送订阅。

await pubsub.createSubscription(
    'my-subscription',
    'my-topic',
    endpoint: Uri.parse('https://server.example.com/push'));

通过此订阅,所有消息都将被发送到 endpoint 参数中提供的 URL。
服务器需要通过返回 200 OK
响应来确认消息的接收。

运行测试

如果你想运行端到端测试,需要一个 Google Cloud 项目。
运行这些测试时,需要设置以下环境变量:

GCLOUD_E2E_TEST_PROJECT
GCLOUD_E2E_TEST_KEY

环境变量 GCLOUD_E2E_TEST_PROJECT 的值是
要使用的 Google Cloud 项目的名称。环境变量
GCLOUD_E2E_TEST_KEY 的值是一个 Google Cloud Storage 路径(以 gs:// 开头),
指向一个服务账户的 JSON 密钥文件,该账户提供对 Cloud Project 的访问权限。

https://github.com/ariscybertech/aris_gcloud