Index: README.md |
diff --git a/README.md b/README.md |
index 698340fec8f83aed0d33313cd5cc69a516639876..0d09481eec603e4e8e8d7e54cfcb02e1040988b4 100644 |
--- a/README.md |
+++ b/README.md |
@@ -1,16 +1,216 @@ |
-## Google Cloud Platform |
+## Google Cloud Platform support package (gcloud) |
-High level interface for Google Cloud Platform APIs |
+This `gcloud` packages provides a high level "idomatic Dart" interface to |
+some of the most widely used Google Cloud Platform services. Currently the |
+following services are supported: |
+ |
+ * Cloud Datastore |
+ * Cloud Storage |
+ * Cloud Pub/Sub |
+ |
+The APIs in this package are all based on the generic generated APIs in the |
+[googleapis] and [googleapis_beta] packages. |
+ |
+This means that the authentication model for using the APIs in this package |
+uses the [googleapis_auth] package. |
+ |
+Note that this package is only intended for being used with the standalone VM |
+in a server or command line application. Don't expect this package to work on |
+the browser. |
+ |
+The code snippets below demonstrating to use of this package all assume that |
+the following imports are present: |
+ |
+```dart |
+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'; |
+``` |
+ |
+### Getting access to the APIs |
+ |
+The first step in using the APIs is to get an authenticated HTTP client and |
+with that create API class instances for accessing the different APIs. The |
+code below assumes that you have a Google Cloud Project called `my-project` |
+with credentials for a service account from that project stored in the file |
+`my-project.json`. |
+ |
+```dart |
+// Read the service account credentials from the file. |
+var jsonCredentials = new File('my-project.json').readAsStringSync()); |
kustermann
2015/03/24 17:53:28
Remove final ')'
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+var credentials = new auth.ServiceAccountCredentials.fromJson(jsonCredentials); |
+ |
+// Get an HTTP authenticated client using the service account credentials. |
+var scopes = [] |
+ ..addAll(dastore_impl.DatastoreImpl.SCOPES); |
+ ..addApp(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'); |
+``` |
+ |
+All the APIs in this package supports the use of 'service scopes'. Service |
+scopes are described in details below. |
+ |
+```dart |
+ss.fork(() { |
+ // register the services in the new service scope. |
+ registerDbService(db); |
+ registerStorageService(storage); |
+ registerPubSubService(pubsub); |
+ |
+ // Run application which uses these services. |
+}); |
+``` |
+ |
+When other parts of the application is running inside a service scope with |
kustermann
2015/03/24 17:53:28
is -> are
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+these services registered they are directly available through getters like this: |
+ |
+```dart |
+dbService. |
+storageService. |
+pubsubService. |
+``` |
+ |
+This way it is not necessary to pass the service objects around in your code. |
+ |
+### Use with App Engine |
+ |
+The `gcloud` package is also integrated into the Dart [appengine] package so |
+that when running Dart on App Engine assessing the `gcloud` services is well |
kustermann
2015/03/24 17:53:28
assessing -> accessing
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+integrated into both the local developemnt server and the authentication model |
kustermann
2015/03/24 17:53:28
developemnt -> development
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+for gaining access to Google Cloud Platform services for App Engine |
+applications. |
+ |
+## Cloud Datastore |
+Google Cloud Datastore provide a NoSQL, schemaless database for storing |
+non-relational data. See the product page |
+[https://cloud.google.com/datastore/][Datastore] for more information. |
kustermann
2015/03/24 17:53:28
Is this link valid?
I thought it's either (...)[.
Søren Gjesse
2015/03/25 08:28:26
It is I think that (...)[...] is not working. At l
|
+ |
+The Cloud Datastore API provide mapping of Dart objects to entities stored |
kustermann
2015/03/24 17:53:28
provide -> provides a
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+in the Datastore. The following example shows how to annotate a class to |
+make it possible to store instances of it in the Datastore. |
+ |
+```dart |
+@db.Kind() |
+class Person extends db.Model { |
+ @db.StringProperty() |
+ String name; |
+ |
+ @db.IntProperty() |
+ int age; |
+} |
+``` |
+ |
+The `Kind` annotation tell that instances of this class can be stored. The |
+class must also inherit from `Model`. Now to store into the Datastore create |
kustermann
2015/03/24 17:53:28
to store -> to store an object in the
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+an instance and use the `commit` function. |
+ |
+```dart |
+var person = new Person() |
+ ..name = '' |
+ ..age = 42; |
+await db.commit(inserts: [person]); |
+``` |
+ |
+The function `query` is used to build a `Query` object which can be run to |
+perform the query. |
+ |
+```dart |
+var persons = await db.query(Person).run().toList(); |
+``` |
+ |
+NOTE: This package include a lower level API provided through the class |
+`Datastore` on top of which the `DatastoreDB` API is build. The main reason |
+for this additional API level is to bridge the gap between the different APIs |
+exposed inside App Engine and through the public REST API. We reserve the |
+rights to modify and maybe even remove this additional layer at any time. |
+ |
+## Could Storage |
+Google Cloud Storage provide a highly available object storage (aka BLOB |
+store). See the product page [https://cloud.google.com/storage/][GCS] |
+for more information. |
+ |
+In Cloud Storage the objects (BLOBs) are organized in _buckets_. Each bucket |
+has a name in a global namespace. The following code creates a new bucket |
+named `my-bucket` and writes the content of the file `my-file.txt` to the |
+object named `my-object`. |
+ |
+```dart |
+var bucket = storage.createBucket('my-bucket'); |
kustermann
2015/03/24 17:53:28
is an 'await' missing here?
Søren Gjesse
2015/03/25 08:28:26
Yes, added.
|
+new File('my-file.txt').openRead().pipe(bucket.write('my-object')); |
+``` |
+ |
+The following code will read back the object. |
+ |
+```dart |
+bucket.read('my-object').pipe(new File('my-file-copy.txt').openRead()); |
kustermann
2015/03/24 17:53:28
openRead -> openWrite
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+``` |
+ |
+## Cloud Pub/Sub |
+Google Cloud Pub/Sub provide many-to-many, asynchronous messaging. See the |
kustermann
2015/03/24 17:53:28
provide -> provides
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+product page [https://cloud.google.com/pubsub/][PubSub] for more information. |
+ |
+Cloud Pub/Sub ues two concepts for messaging. _Topics_ are used if you want |
kustermann
2015/03/24 17:53:28
ues -> uses
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+to send messages and _subscriptions_ are used to subscribe to topics and |
+receive the messages. |
kustermann
2015/03/24 17:53:28
Maybe add: "This de-couples the producer of a mess
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+ |
+The following code creates a _topic_ and sends a simple test message: |
+ |
+```dart |
+var topic = await pubsub.createTopic('my'topic'); |
+await topic.publishString('Hello, world!') |
+``` |
+ |
+```dart |
+var subscription = |
+ await pubsub.createSubscription('my-subscription', 'my-topic); |
+var pullEvent = await subscription.pull(); |
+await pullEvent.acknowledge() |
kustermann
2015/03/24 17:53:28
maybe add a comment that `pullEvent` has the real
Søren Gjesse
2015/03/25 08:28:26
Added
print(pullEvent.message.asString);
|
+``` |
+ |
+It is also possible to receive messages using push events instead of pulling |
+from the subscription. To do this the subscription should be configured as a |
+push subscription with an HTTP endpoint. |
+ |
+```dart |
+await pubsub.createSubscription( |
+ 'my-subscription', |
+ 'my-topic', |
+ endpoint: Uri.parse('https://server.example.com/push')); |
+``` |
+ |
+With this subscription all messages will be send to the URL provided in the |
+`endpoint` argument. The server will acknowledge the reception of the message |
kustermann
2015/03/24 17:53:28
will -> needs to
Søren Gjesse
2015/03/25 08:28:26
Done.
|
+with a `200 OK` reply. |
### Running tests |
If you want to run the end-to-end tests, a Google Cloud project is required. |
-When running these tests the following envrionment variables needs to be set: |
+When running these tests the following environment variables needs to be set: |
GCLOUD_E2E_TEST_PROJECT |
GCLOUD_E2E_TEST_KEY |
The vaule of the environment variable `GCLOUD_E2E_TEST_PROJECT` is the name |
of the Google Cloud project to use. The value of the environment variable |
-`GCLOUD_E2E_TEST_KEY` is a Google Cloud Storage path (starting wiht `gs://`) |
+`GCLOUD_E2E_TEST_KEY` is a Google Cloud Storage path (starting with `gs://`) |
to a JSON key file for a service account providing access to the Cloud Project. |
+ |
+[Datastore]: https://cloud.google.com/datastore/ |
+[GCS]: https://cloud.google.com/storage/ |
+[PubSub]: https://cloud.google.com/pubsub/ |
+[googleapis]: https://pub.dartlang.org/packages/googleapis |
+[googleapis_beta]: https://pub.dartlang.org/packages/googleapis_beta |
+[googleapis_auth]: https://pub.dartlang.org/packages/googleapis_beta |
+[appengine]: https://pub.dartlang.org/packages/appengine |